用Java解析CSV文件的一部分

时间:2016-01-07 21:55:13

标签: java csv

我需要处理一个实际包含多个表的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)开头,并以两个空行结束。

3 个答案:

答案 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个部分中的文本(按照示例描述),其处理很简单,例如:

  1. 创建Java BufferedReader对象以逐行读取文件
  2. 阅读第1节并提取键值对
  3. 读取并忽略其余行,直到CSV标题(第2节)
  4. 使用标题和其他参数(逗号分隔符,引号等)初始化CSV解析器(commons-csv或其他)
  5. 使用解析器处理每个后续行
  6. 解析器将提供一些类似迭代器的API,以将每行读入Java对象,从中读取字段将是微不足道的。这种方法远远优于在内存中预加载所有内容,因为它可以容纳任何文件大小。