まえがき
ファイルから読み込んだ文字は前から解釈することが多いですが、ある程度のまとまり(例えば1行)を読みこんでから後ろから解釈した方が楽な場合があります。
例えば、区切り文字で分割しての処理が難しい場合に、後ろの項目を取得を楽にできるようになります。
今回は、特殊なフォーマットのCSVファイルから後ろの項目を取得する例を考えてみます。
サンプルコード
要件
今回の例では、以下のCSVファイルがインプットであると仮定します。
要件は、一番最後の項目であるユーザー名のみを抜き出して表示する、とします。
- 1項目目…連番(7文字固定の数値)
- 2項目目…コメント(改行文字は含まない、カンマ(区切り文字)はエスケープされない)
- 3項目目…ユーザー名(改行文字やカンマは含まれない)
2項目目にエスケープされないカンマが入ってくる所がポイントです。
単純にStringクラスのsplitメソッドでカンマ区切りのレコードとして処理してしまうと、項目数がその時々で変わってしまうという難しさがあります。
そこで、今回のサンプルコードでは、1行を読み込んでから後ろから文字列を組み立てる、ということをしています。
ソースコード
FileReadWriteMain3.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class FileReadWriteMain3 { public static void main(String[] args) { // 1バイトずつ読込(テキストファイルとして処理) BufferedReader br = null; BufferedWriter bw = null; try { // 入出力ファイルパス br = new BufferedReader (new InputStreamReader (new FileInputStream("C:\\tmp\\test.csv"),"MS932")); bw = new BufferedWriter (new OutputStreamWriter (new FileOutputStream("C:\\tmp\\test_out.csv"), "MS932")); // 読み込んだ箇所を保持 StringBuilder sb = new StringBuilder(); // データ読み込みループ while (true){ // 1行読み込み String str = br.readLine(); if (str == null) { break; } // 読み込んだ行を後ろから解釈 sb.delete(0, sb.length()); for(int i = str.length() - 1; i >= 0; i--) { if (String.valueOf(str.charAt(i)).equals(",")) { // 3項目目の終わりとして判定しループを抜ける break; } else { // 3項目目(ユーザー名)を組み立てる sb.insert(0,str.charAt(i)); } } // 組み立てたユーザー名を出力 bw.write(sb.toString()); bw.newLine(); } // 例外処理 } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
処理例
入力ファイル
1 2 |
0000001,コメントの中にカンマ,がある,hoge 0000002,コメント,fuga |
出力ファイル
1 2 |
hoge fuga |
あとがき
前々回、前回に続いて、特殊なフォーマットのファイルの読み込み方・解釈の方法について紹介しました。
今回の例のような特殊なフォーマットのファイルは実際にはなかなか目にしないと思いますが、汎用的な処理では解釈できないフォーマットのファイルを扱わなければならなくなることは珍しくありません。
(この記事も、実際に後ろから解釈して対処したことがあったので書いた記事です)
汎用的な処理では解釈できない時に、ファイルを1文字ずつ解釈するテクニックを有効活用できるので、この発想だけでも覚えておいて損はありません。
株式会社サイゼントでは、即戦力のJavaプログラマーを育てるための書籍「絶対にJavaプログラマーになりたい人へ」をKindleで販売しています。

同じく、Spring Frameworkについてきめ細かく解説した別冊も販売中です。

また、上記の書籍をテキストとして用いたプログラミングスクール「サイゼントアカデミー」も開校しています。
このスクールは、受託開発事業・SES事業である弊社が、新入社員向けの研修で培ったノウハウを詰め込んだものです。

ご興味がある方は、上記画像から個別ページにアクセスしてみてください!
コメント