複数の同じ形式のCSVファイルを、1回の解析プロセッサの指定で実行することを
csv4j で考えた。
CSVFileProcessorと似たメソッドを持つクラスと、CSVLineProcessor インターフェースにそっくりなものを用意する
→ ExCSVLineProcessor
1行解析で実行される1行読込みプロセッサ
これと、
この中で読込み中のファイル情報が判るように、File インスタンス参照できるようにした。
もちろん、今までのCSVLineProcessorも使えるようにする
import java.io.File;
import java.util.List;
/**
* ExCSVFileProcessor#processStream で指定する CSVLineProcessor 拡張
* processHeaderLine , processDataLine で 読込中の File を参照可能とする
*/
public interface ExCSVLineProcessor{
void processHeaderLine(int line,List<String> fieldNames,File file);
void processDataLine(int line,List<String> fieldValues,File file);
boolean continueProcessing();
}
---------------------
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sf.csv4j.CSVLineProcessor;
import net.sf.csv4j.CSVReader;
import net.sf.csv4j.CSVStreamProcessor;
import net.sf.csv4j.ParseException;
import net.sf.csv4j.ProcessingException;
/**
* 複数CSV 解析プロセッサ.
*/
public class ExCSVFileProcessor{
private String charsetName;
public ExCSVFileProcessor(){
this.charsetName = "UTF-8";
}
public ExCSVFileProcessor(String charsetName){
this.charsetName = charsetName;
}
public int processFiles(Collection<String> paths,CSVLineProcessor processor)
throws IOException, ParseException, ProcessingException{
List<File> list = new ArrayList<File>();
for(String s : paths){
list.add(new File(s));
}
return processFiles(list,processor);
}
public int processFiles(List<File> files,CSVLineProcessor processor)
throws IOException, ParseException, ProcessingException{
for(File f : files){
if (!f.exists()) throw new IOException("Not found csv file : "+f.getPath());
if (!f.isFile()) throw new IOException("No csv file : "+f.getPath());
}
int cnt=0;
for(File f : files){
cnt += new CSVStreamProcessor()
.processStream(new InputStreamReader(new FileInputStream(f),this.charsetName),processor);
}
return cnt;
}
public int processFiles(Collection<String> paths,ExCSVLineProcessor processor)
throws IOException, ParseException, ProcessingException{
List<File> list = new ArrayList<File>();
for(String s : paths){
list.add(new File(s));
}
return processFiles(list,processor);
}
public int processFiles(List<File> files,ExCSVLineProcessor processor)
throws IOException, ParseException, ProcessingException{
for(File f : files){
if (!f.exists()) throw new IOException("Not found csv file : "+f.getPath());
if (!f.isFile()) throw new IOException("No csv file : "+f.getPath());
}
int cnt=0;
for(File f : files){
cnt += new CSVStreamProcessor(){
public int processFiles(final File file,String charName
,final ExCSVLineProcessor _p)
throws IOException, ProcessingException, ParseException{
InputStreamReader is
= new InputStreamReader(new FileInputStream(file),charName);
CSVReader reader = new CSVReader(new BufferedReader(is),'#');
try{
int lineCnt = 0;
while(_p.continueProcessing()){
final List<String> fields = reader.readLine();
if (fields.size()==0){ break; }
try{
if (lineCnt==0){
_p.processHeaderLine(reader.getLineNumber(),fields,file);
}else{
_p.processDataLine(reader.getLineNumber(),fields,file);
}
}catch(Exception e){
throw new ProcessingException(e,reader.getLineNumber());
}
lineCnt++;
}
return lineCnt;
}finally{
reader.close();
}
}
}.processFiles(f,this.charsetName,processor);
}
return cnt;
}
}