ファイルサイズは11kbとコンパクトですので、GAEからAndroidさらにはGWTなどで活用できると思います。 速度も問題ないと思います。 (GWTで使うにはReader・Writerクラスを改造する必要があります。修正したもの) CSVの形式デフォルトの形式カンマ区切りで、データーをダブルクォート(")で囲み、データー中のダブルクォートはダブルクォートでエスケープされます。 例 "1","名前","7","テキスト","22"
指定出来るCSV形式区切りキャラクター及び、行文字を指定できます。 囲むキャラクターを指定したり、囲まないよう指定もできます。ただし、指定なしだと区切り文字はエスケープされないので問題が起こりやすいです。 囲むキャラクターのエスケープキャラクターも指定できます。エスケープ無しも可能(デフォルトでは"は""となるが、これを\"という風に指定可能)
できない/やり方がわからないこと囲むキャラクターは無しだけど、データー中の区切り文字はエスケープするやり方がわからない。 出力時、囲む必要がないデーターは囲まない方法がわからない。無駄に囲むと逆に読みにくかったりもしますし、データーも大きくなります。 ただし読み込み時はGoogle スプレットシートのCSV出力でもある、この形式は読み込める。 例 (1,"名前=""X""",7,テキスト,22) 改行を含む文字の改行コード指定デフォルトの改行は\nです。改行を指定できないと、Windowsでそのまま出力するときに不便になります。 ソースコードを見てみますと、Parser中に"\n"を追加していました。 ですので、Loop内で、csv[i]=csv[i].replace("\n", "\r\n"); という風に自分で\nを置き換えるといいですね。 使い方読み込みCSVReaderを使ってReaderクラスから読み込みます。区切り文字や囲み文字などは、コンストラクタで指定します。先頭の行をスキップも指定できます。詳しくはCSVReader API参照
あとは、まとめて読み込む場合は、 (Bufferの関係かどうかわかりませんが、時々、変なことがありますので、私はreadNextしか使っていません) CSVReader reader=new CSVReader(new FileReader(new File("null.csv"))); List<String[]> datas=reader.readAll(); 行ごとに読み込む場合は、以下のようになります。 CSVReader reader=new CSVReader(new FileReader(new File("null.csv"))); String[] csv=reader.readNext(); また、Google ドキュメントのSpreadsheetsのCSV保存時とかで使われる、必要がない項目はダブクォートでくくられない形式も読み込めます。
CSVReaderの文字コードCSVReaderではReaderを引数にしますので、Readerが文字コードをどうにかします。 文字コードを明確に指定する場合は、InputStreamReaderを作成して文字コードを指定します。 以下はエンコードがUTF-8で1行目がヘッダーなのでスキップしてCSVファイルを読み込むCSVReaderの作り方です。 InputStream input=new FileInputStream(path); InputStreamReader ireader=new InputStreamReader(input, "UTF-8"); CSVReader reader = new CSVReader(ireader,',','"',1); 書き込みCSVWriterクラスを使います。区切り文字や囲み文字などはコンストラクタで指定します。 最後にflush()かclose()しないと出力されないことがあります。詳しくは、CSVWriter APIを参照 行単位で書き出す場合、writeNextを使います。 String test[]={"\"",","}; CSVWriter writer = new CSVWriter(new PrintWriter(System.out)); writer.writeNext(test); writer.flush() まとめて書き出す、writeAll(List<String[]>)というメソッドもあります。 単純に分割複数の行でなく、単純な行の場合は、CSVParserを使うのが楽です。 CSVReaderでも内部ではCSVParserを呼び出しています。 使い方は単純でインスタンスを作成してタブやカンマなどの分割キャラクターや、シングルやダブルのクォートキャラクターを指定するだけです。 何も指定しないと、デフォルトのカンマとダブルクォートのパーサーが出きます。 CSVParser() CSVParser(char separator 分割キャラクター) CSVParser(char 分割キャラクター ,char クォートキャラクター) あとは、parseLineを呼び出します。よく使う場合は、s String[] vs = csvparser.parseLine(line); "a,,," とかの文字列ですと、配列の長さ1つになります。 普通の時は問題起きにくいですが、HTMLのTableのTDとか作っていると問題になります。 CSVからJavaBeanを生成する非常に簡単にCSVからJavaBeanを作成出きます。 例えばは、以下のようなクラスに変換したい場合 public class City { private String name=""; private int score; private String comment=""; //getter setterは略 } クラスとコラム名を指定すれば、以下のようにすれば、簡単にJavaBeanになります。 コラム名に無効な値を入れておくことで、項目をスキップすることもできます。 ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy(); strat.setType(City.class); String[] columns = new String[] {"name", "score", "comment"}; strat.setColumnMapping(columns); CsvToBean csv = new CsvToBean(); List<City> list = csv.parse(strat, reader);
ただし、途中の数字の項目が空の時は、NumberFormatExceptionが発生してしまうので気をつけてください。 例えば2つ目の項目が数字だとすると以下のようになります。 NewYork,10,good //ok Tokyo, //エラー "" を数字に変換しようとする Pari,,good //エラー ""を数字に変換しようとする London //ok 数字を読み取らない ただこの場合、文字列を受け取る専用のメソッドを用意して、そのsetter名に合わせて コラムンの名前を{"name", "scoreString", "comment"}を変更することで回避できます。 もちろんOpenCSVはオープンソースのCSVParserですので、APIのソースコードをエラーでないように変更してもいいのですが public class City { private int score; public void setScoreString(String scoreString) { try{ score=Integer.parseInt(scoreString); }catch(Exception e){ //e.printStackTrace(); } } } その他ResultSetをCSVとして出力したりもできます。 GWTでOpenCSVを使うそのまま使うGWT-CSVParser - GWTでも動くようにしてみました。 改造して使うGWTではCSVParserのOpenCSVはそのまま使えません。 GWTではReader・Writerクラスが使えないので、こんな感じに改造する必要があります。
AndroidでOpenCSVを使う普通に使えます。コーテションで囲まれている文字分割や複数行のCSV解析には便利です。 単純なカンマ区切りのぶんかつの場合、CSVParserのparseは、文字列のsplit()に比べて少し遅いです。 ただ、複数行からなるデーターの解析では、普通の方法ではreadLine()するにに、BufferedReaderまで作る必要があるためか CSVReaderの方が速いケースもあります。 AndroidのIO関連は遅いのでなるべく避けたい所です。 OpenCSVと文字化け基本的には、Readerから読み込み、Writerに書きだすので、OpenCSVが原因で文字化けは起こりえません。 ただし、FileReaderとかでいきなり読み込むと文字コードの自動判定失敗することがあるので InputStreamReaderで、文字コードを指定して読み込みましょう。文字コードの判別が怪しい時は、juniversalchardet (UTF-8は先頭のゴミに注意)とか使いましょう。 あと、SJISだと、Windows-31J/MS932とは、違いがあるので気を付けましょう。SJISで読み込んだ場合、㈱とか化けるのは、これがWindows-31J 機種依存コードだからです。 |
Java ライブラリー >