繁体   English   中英

用Java解析CSV文件的一部分

[英]Parsing part of a CSV file in Java

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

使用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();
}

您可以使用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个部分的文本,按照示例进行了描述,则其处理非常简单,例如:

  1. 创建一个Java BufferedReader对象以逐行读取文件
  2. 阅读第1节并提取键值对
  3. 读取并忽略剩余的行,直到CSV标头(第2节)
  4. 使用标头和其他参数(逗号分隔符,引号等)初始化CSV解析器( commons-csv或其他)
  5. 使用解析器处理每个后续行

解析器将提供类似于迭代器的API,以将每行读入Java对象,从中读取字段将变得很简单。 这种方法大大优于将所有内容预加载到内存中,因为它可以容纳任何文件大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM