我需要处理一个实际包含多个表的CSV文件,如下所示:
"-------------------- Section 1 --------------------"
"Identity:","ABC123"
"Initials:","XY"
"Full Name:","Roger"
"Street Address:","Foo St"
"-------------------- Section 2 --------------------"
"Line","Date","Time","Status",
"1","30/01/2013","10:49:00 PM","ON",
"2","31/01/2013","8:04:00 AM","OFF",
"3","31/01/2013","11:54:00 PM","OFF",
"-------------------- Section 3 --------------------"
我想用commons-csv之类的内容解析每个部分中的块,但是单独处理每个部分会有所帮助,在双换行符处停止,就像它是文件的结尾一样。有没有人解决过这个问题?
注意:文件可以任意长,并且可以包含任意数量的部分,因此如果可能的话我会在一次通过之后。每个部分似乎都以标题标题(------- title ------\n\n
)开头,并以两个空行结束。
答案 0 :(得分:3)
如何使用java.io.FilterReader?您可以通过反复试验找出需要覆盖的Reader方法。您的自定义课程必须提前读完整行,看看它是否属于' Section'线。如果是,则返回EOF以停止commons-csv
解析器。然后,您可以阅读自定义类的下一部分。不优雅,但它可能会奏效。给出的例子:
class MyReader extends FilterReader {
private String line;
private int pos;
public MyReader(BufferedReader in) {
super(in);
line = null;
pos = 0;
}
@Override
public int read() {
try {
if ( line == null || pos >= line.length() ) {
do {
line = ((BufferedReader)in).readLine();
} while ( line != null && line.length() == 0 );
if ( line == null ) return -1;
line = line + "\r\n";
pos = 0;
}
if ( line.contains("-------------------- Section ") ) {
line = null;
return -1;
}
return line.charAt(pos++);
} catch ( Exception e) { throw new RuntimeException(e); }
}
}
你会像这样使用它:
public void run() throws Exception {
BufferedReader in = new BufferedReader(new FileReader(ReadRecords.class.getResource("/records.txt").getFile()));
MyReader reader = new MyReader(in);
int c;
while( (c=reader.read()) != -1 ) {
System.out.print((char)c);
}
while( (c=reader.read()) != -1 ) {
System.out.print((char)c);
}
while( (c=reader.read()) != -1 ) {
System.out.print((char)c);
}
reader.close();
}
答案 1 :(得分:1)
您可以使用String.split()
访问各个CSV部分:
for (String csv : content.split("\"----+ Section \\d+ ----+\"")) {
// Skip empty sections
if (csv.length() == 0) continue;
// parse and process each individual "csv" section here
}
答案 2 :(得分:0)
假设文件包含2个部分中的文本(按照示例描述),其处理很简单,例如:
Java
BufferedReader
对象以逐行读取文件CSV
标题(第2节)CSV
解析器(commons-csv
或其他)解析器将提供一些类似迭代器的API,以将每行读入Java
对象,从中读取字段将是微不足道的。这种方法远远优于在内存中预加载所有内容,因为它可以容纳任何文件大小。