首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取大csv文件,使用uniVocity解析器验证和写出

读取大csv文件,使用uniVocity解析器验证和写出
EN

Stack Overflow用户
提问于 2015-12-14 14:31:59
回答 1查看 2.9K关注 0票数 3

我需要解析一个大的csv文件(2gb)。必须验证这些值,必须删除包含“坏”字段的行,并且应该输出一个只包含有效行的新文件。

为此,我选择了uniVocity解析器库。请帮助我理解这个库是否适合这个任务,以及应该使用什么方法。

  1. 给定文件大小,在uniVocity中组织读->验证->写的最好方法是什么?一次读取所有行,还是使用迭代器样式?在将经过分析和验证的行写入文件之前,应该将它们存储在哪里?
  2. 是否有一种在Univocity中按索引访问行值的方法?类似于row.getValue(3)?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-15 08:40:37

我是这个图书馆的作者,让我试着帮你:

  1. 首先,不要尝试一次读取所有行,因为您将用大量数据填充您的内存。
  2. 可以按索引获取行值。

读取/验证/写入的速度更快的方法是使用具有RowProcessor并决定何时写入或跳过行的CsvWriter。我认为以下代码会对您有所帮助:

定义输出:

代码语言:javascript
复制
private CsvWriter createCsvWriter(File output, String encoding){
    CsvWriterSettings settings = new CsvWriterSettings();
    //configure the writer ...

    try {
        return new CsvWriter(new OutputStreamWriter(new FileOutputStream(output), encoding), settings);
    } catch (IOException e) {
        throw new IllegalArgumentException("Error writing to " + output.getAbsolutePath(), e);
    }
}

重定向输入

代码语言:javascript
复制
//this creates a row processor for our parser. It validates each row and sends them to the csv writer.
private RowProcessor createRowProcessor(File output, String encoding){
    final CsvWriter writer = createCsvWriter(output, encoding);
    return new AbstractRowProcessor() {

        @Override
        public void rowProcessed(String[] row, ParsingContext context) {
            if (shouldWriteRow(row)) {
                writer.writeRow(row);
            } else {
                //skip row
            }
        }

        private boolean shouldWriteRow(String[] row) {
            //your validation here
            return true;
        }

        @Override
        public void processEnded(ParsingContext context) {
            writer.close();
        }
    };
}

配置解析器:

代码语言:javascript
复制
public void readAndWrite(File input, File output, String encoding) {

    CsvParserSettings settings = new CsvParserSettings();
    //configure the parser here

    //tells the parser to send each row to them custom processor, which will validate and redirect all rows to the CsvWriter
    settings.setRowProcessor(createRowProcessor(output, encoding));

    CsvParser parser = new CsvParser(settings);
    try {
        parser.parse(new InputStreamReader(new FileInputStream(input), encoding));
    } catch (IOException e) {
        throw new IllegalStateException("Unable to open input file " + input.getAbsolutePath(), e);
    }
}

为了获得更好的性能,还可以将行处理器封装在ConcurrentRowProcessor中。

代码语言:javascript
复制
settings.setRowProcessor(new ConcurrentRowProcessor(createRowProcessor(output, encoding)));

这样,行的写入将在一个单独的线程中执行。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34269510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档