CSV文件操作的两个类
贴这儿留着回去看一下
package jp.ac.wakhok.tomoharu.csv;
import java.util.Vector;
import java.util.Enumeration;
/**
* CSV形式の1行分のデータ内容を保持するクラス。
* CSV形式への書き出し、書き出しの際のエンクォートの指定、
* 項目の追加などが可能である。
*
* @version 1.0.1 (1999.4.13)
*/
public class CSVLine {
public static final String copyright =
"Copyright 1997 TAMURA Kent" + "\n" +
"Copyright 1999 ANDOH Tomoharu";
private Vector items;
/**
* 空のCSVLine のインスタンスを作成する。
*/
public CSVLine() {
items = new Vector();
}
/**
* 引数で指定された文字列を、末尾に追加する。
*
* @param item 追加する文字列
*/
public void addItem(String item) {
addItem(item, false);
}
/**
* 引数で指定された文字列を、末尾に追加する。
* CSV形式のデータとして出力されるとき、その項目を強制的に
* エンクォートするかどうかを引数によって指定する。
*
* @param item 追加する文字列
* @param enquote trueだと、強制的にエンクォートされる。
*/
public void addItem(String item, boolean enquote) {
items.addElement(new Element(item, enquote));
}
/**
* 引数で指定されたCSVTokenizerに含まれるすべての項目を、
* 末尾に追加する。
*
* @param ct CSVTokenizerのインスタンス。ここに含まれている項目
* は、末尾に追加される。
* @see jp.ac.wakhok.tomoharu.csv.CSVTokenizer
*/
public void addItem(CSVTokenizer ct) {
while (ct.hasMoreTokens()) {
String item = ct.nextToken();
items.addElement(new Element(item));
}
}
/**
* 1行のCSV形式のデータを返す。
*
* @return 1行のCSV形式のデータ
*/
public String getLine() {
StringBuffer list = new StringBuffer();
for (int n = 0; n < items.size(); n ++) {
Element element = (Element)items.elementAt(n);
String item = element.getItem();
list.append(item);
if (items.size() - 1 != n) {
list.append(',');
}
}
return new String(list);
}
/**
* 1行の項目数を返す。
*
* @return CSVLineに含んでいる項目の数
*/
public int size() {
return items.size();
}
/**
* n番目の項目を String で返す。
*
* @param n 項目の番号 [0 ~ size()-1]
* @return n番目の文字列。エンクォートはしない。
*/
public String getItem(int n) {
Element element = (Element)items.elementAt(n);
return element.getRawItem();
}
/**
* n番目の項目を削除する。
*
* @param n 項目の番号 [0 ~ size()-1]
*/
public void removeItem(int n) {
items.removeElementAt(n);
}
/**
* CSVLineの項目のリストを返す。
*
* @return このCSVLineに含まれている文字列のリスト
* @see java.util.Enumeration
*/
public Enumeration elements() {
return new CSVLineEnumerator(items);
}
/**
* CSVLineに含まれるそれぞれの項目を保持するインナークラス。
*/
class Element {
private String item;
private boolean enquote;
Element(String item) {
this(item, false);
}
Element(String item, boolean enquote) {
this.item = item;
this.enquote = enquote;
}
/**
* 指定されていれば、エンクォートを行う。
*/
public String getItem() {
return enquote(item, enquote);
}
/**
* エンクォートは一切しない。
*/
public String getRawItem() {
return item;
}
}
/**
* elements()メソッドで返される Enumerationクラス
*/
class CSVLineEnumerator implements Enumeration {
private Vector items;
private int n;
CSVLineEnumerator(Vector items) {
this.items = items;
n = 0;
}
public Object nextElement() {
n ++;
Element element = (Element)items.elementAt(n-1);
return element.getRawItem();
}
public boolean hasMoreElements() {
return n < items.size();
}
}
/**
* 引数の文字列 item を CSV で出力できるように加工した文字列を
* 返す。
* item が " か , を含んでいるときには item 全体を " で囲み
* (エンクォートし)、" を "" に置き換える。また" と , のどち
* らも含んでいないときは、item をそのまま返す。
*
* @param item 処理したい文字列
* @return item を処理した文字列
*/
public static String enquote(String item) {
return enquote(item, false);
}
/**
* 引数の文字列 item を CSV で出力できるように加工した文字列を
* 返す。
* enquote が true のときは、強制的にエンクォートする。つまり、
* item を " で囲った文字列を返す。
* false のときは、エンクォートするかどうかは、item による。
* item が " か , を含んでいるときには item 全体を " で囲み
* (エンクォートし)、" を "" に置き換える。また" と , のどち
* らも含んでいないときは、item をそのまま返す。
* item が空、つまり長さがゼロの文字列だった場合、何もせずに
* 空の文字列をそのまま返す。
*
* @param item 処理したい文字列
* @param enquote trueなら強制的にエンクォートする
* @return item を処理した文字列
*/
public static String enquote(String item, boolean enquote) {
if (item.length() == 0) {
return item;
}
if (item.indexOf('"') < 0 &amp;&amp; item.indexOf(',') < 0 &amp;&amp; enquote == false) {
return item;
}
// StringBufferのサイズは、最も異常な場合を想定した。
// 文字列 """"" をエンクォートして出力するようなときのこと。
StringBuffer sb = new StringBuffer(item.length() * 2 + 2);
sb.append('"');
for (int ind = 0; ind < item.length(); ind ++) {
char ch = item.charAt(ind);
if ('"' == ch) {
sb.append("\"\"");
} else {
sb.append(ch);
}
}
sb.append('"');
return new String(sb);
}
}
package jp.ac.wakhok.tomoharu.csv;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
* 1行のCSV形式のデータを解析し、それぞれの項目に分解するクラス。
* CSV形式に対応した java.util.StringTokenizer のようなもの。
*
* @version 1.0.1 (1999.4.6)
* @author TAMURA Kent <[email protected]></[email protected]>
* @author ANDOH Tomoharu <[email protected]></[email protected]>
*/
public class CSVTokenizer implements Enumeration {
public static final String copyright =
"Copyright 1997 TAMURA Kent" + "\n" +
"Copyright 1999 ANDOH Tomoharu";
private String source; // 対象となる文字列
private int currentPosition; // 次の読み出し位置
private int maxPosition;
/**
* CSV 形式の line を解析する CSVTokenizer のインスタンスを
* 作成する。
*
* @param line CSV形式の文字列 改行コードを含まない。
*/
public CSVTokenizer(String line) {
source = line;
currentPosition = 0;
maxPosition = line.length();
}
/**
* 次のカンマがある位置を返す。
* カンマが残っていない場合は nextComma() == maxPosition となる。
* また最後の項目が空の場合も nextComma() == maxPosition となる。
*
* @param ind 検索を開始する位置
* @return 次のカンマがある位置。カンマがない場合は、文字列の
* 長さの値となる。
*/
private int nextComma(int ind) {
boolean inquote = false;
while (ind < maxPosition) {
char ch = source.charAt(ind);
if (!inquote &amp;amp;amp;&amp;amp;amp; ch == ',') {
break;
} else if ('"' == ch) {
inquote = !inquote; // ""の処理もこれでOK
}
ind ++;
}
return ind;
}
/**
* 含まれている項目の数を返す。
*
* @return 含まれている項目の数
*/
public int countTokens() {
int i = 0;
int ret = 1;
while ((i = nextComma(i)) < maxPosition) {
i ++;
ret ++;
}
return ret;
}
/**
* 次の項目の文字列を返す。
*
* @return 次の項目
* @exception NoSuchElementException 項目が残っていないとき
*/
public String nextToken() {
// ">=" では末尾の項目を正しく処理できない。
// 末尾の項目が空(カンマで1行が終わる)場合、例外が発生して
// しまうので。
if (currentPosition > maxPosition)
throw new NoSuchElementException(toString()+"#nextToken");
int st = currentPosition;
currentPosition = nextComma(currentPosition);
StringBuffer strb = new StringBuffer();
while (st < currentPosition) {
char ch = source.charAt(st++);
if (ch == '"') {
// "が単独で現れたときは何もしない
// 項目が""だった時も何もしない added by sandaas, 2006/11/22
if ((st < currentPosition) &amp;amp;amp;&amp;amp;amp; (source.charAt(st) == '"')
&amp;amp;amp;&amp;amp;amp; (strb.length() > 0)) {
strb.append(ch);
st ++;
}
} else {
strb.append(ch);
}
}
currentPosition ++;
return new String(strb);
}
/**
* <code>nextToken</code>メソッドと同じで、
* 次の項目の文字列を返す。
* ただし返値は、String型ではなく、Object型である。
* java.util.Enumerationを実装しているため、このメソッドが
* ある。
*
* @return 次の項目
* @exception NoSuchElementException 項目が残っていないとき
* @see java.util.Enumeration
* @see jp.ac.wakhok.tomoharu.csv.CSVTokenizer#nextElement()
*/
public Object nextElement() {
return nextToken();
}
/**
* まだ項目が残っているかどうか調べる。
*
* @return まだ項目がのこっているならtrue
*/
public boolean hasMoreTokens() {
// "<=" でなく、"<" だと末尾の項目を正しく処理できない。
return (nextComma(currentPosition) <= maxPosition);
}
/**
* <code>hasMoreTokens</code>メソッドと同じで、
* まだ項目が残っているかどうか調べる。
* java.util.Enumerationを実装しているため、このメソッドが
* ある。
*
* @return まだ項目がのこっているならtrue
* @see java.util.Enumeration
* @see jp.ac.wakhok.tomoharu.csv.CSVTokenizer#hasMoreTokens()
*/
public boolean hasMoreElements() {
return hasMoreTokens();
}
/**
* インスタンスの文字列表現を返す。
*
* @return インスタンスの文字列表現。
*/
public String toString() {
return "CSVTokenizer(\""+source+"\")";
}
}
近期评论