/* * Copyright(C)2005 PoisonSoft * All rights reserved. */ import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; public class CsvReader { // CSVデータの読み出し元 private BufferedReader reader; /** * コンストラクタ。 * @param source CSVデータの読み出し元 */ public CsvReader(Reader source) { reader = new BufferedReader(source); } /** * 次の1行を読み出します。ファイルの終わりならば * 要素数0のリストを返します。 * @return 1行をコンマで分離した各セル文字列のリスト */ public List getCells() throws CsvFormatException, IOException { List list = new ArrayList(); String line = getLine(); if (line == null) { return list; } //System.out.println(line); StringBuffer cell = new StringBuffer(); boolean inQuote = false; int len = line.length(); for (int i = 0; i < len; i++) { char c = line.charAt(i); switch (c) { case ',': if (inQuote) { cell.append(c); } else { list.add(new String(cell)); cell = new StringBuffer(); } break; case '"': if (inQuote) { i++; if (i >= len) { list.add(new String(cell)); return list; } c = line.charAt(i); if (c == '"') { cell.append(c); } else if (c == ',') { inQuote = false; list.add(new String(cell)); cell = new StringBuffer(); } else { throw new CsvFormatException("double quote must be doubled 2 same characters, such as \"\"."); } } else { inQuote = true; } break; default: cell.append(c); } } list.add(new String(cell)); return list; } /** * 次の1行を読み出します。 * \r\nを行末文字として、ここまでを1行とみなします。行末文字は取り除きます。 * 単独の\nは文字として扱います。 * 単独の\rは現れない事を想定しています。 * @return 次の1行。データの終わりに達していたらnull。\n、\t以外の制御文字を含まない */ private String getLine() throws CsvFormatException, IOException { StringBuffer buffer = new StringBuffer();; int c; while ((c = reader.read()) >= 0) { if (c == '\r') { // 次の1文字を読んで行末かどうかを調べる c = reader.read(); if (c < 0) { throw new CsvFormatException("file terminated by \\r"); } if (c == '\n') { return new String(buffer); } else { buffer.append((char) c); } } else { // 行末以外に出現可能な制御文字は\nと\tのみ if (c != '\t' && c != '\n' && Character.isISOControl(c) ) { throw new CsvFormatException("control character exists. [" + Integer.toHexString(c) + "]"); } buffer.append((char) c); } } // 行末文字なしでファイルの末端に達した場合は書式例外とみなす。 if (buffer.length() > 0) { throw new CsvFormatException("file not terminated by \\r\\n"); } return null; } /** * 入力をクローズする */ public void close() throws IOException { reader.close(); } } // end of file