java - 如何使用 supercsv 跳过仅空白的行和具有可变列的行

标签 java csv opencsv supercsv

我正在研究 CSV 解析器要求,并且正在使用 supercsv 解析器库。我的 CSV 文件可以有 25 列(用制表符 (|) 分隔)和最多 100k 行以及附加标题行。

我想忽略纯空白行和包含少于 25 列的行。

我使用带有名称映射(将 csv 值设置为 pojo)和字段处理器(处理验证)的 IcvBeanReader 来读取文件。

我假设 Supercsv IcvBeanReader 默认情况下会跳过空白行。但是如果一行包含的列号少于25个怎么处理?

最佳答案

您可以通过编写自己的分词器轻松地做到这一点。

例如,以下分词器将具有与默认分词器相同的行为,但会跳过任何列数不正确的行。

public class SkipBadColumnCountTokenizer extends Tokenizer {

    private final int expectedColumns;

    private final List<Integer> ignoredLines = new ArrayList<>();

    public SkipBadColumnCountTokenizer(Reader reader, 
            CsvPreference preferences, int expectedColumns) {
        super(reader, preferences);
        this.expectedColumns = expectedColumns;
    }

    @Override
    public boolean readColumns(List<String> columns) throws IOException {
        boolean moreInputExists;
        while ((moreInputExists = super.readColumns(columns)) && 
            columns.size() != this.expectedColumns){
            System.out.println(String.format("Ignoring line %s with %d columns: %s", getLineNumber(), columns.size(), getUntokenizedRow()));
            ignoredLines.add(getLineNumber());
        }

        return moreInputExists;

    }

    public List<Integer> getIgnoredLines(){
        return this.ignoredLines;
    }
}

使用此 Tokenizer 进行简单测试...

@Test
public void testInvalidRows() throws IOException {

    String input = "column1,column2,column3\n" +
            "has,three,columns\n" +
            "only,two\n" +
            "one\n" +
            "three,columns,again\n" +
            "one,too,many,columns";

    CsvPreference preference = CsvPreference.EXCEL_PREFERENCE;
    int expectedColumns = 3;
    SkipBadColumnCountTokenizer tokenizer = new SkipBadColumnCountTokenizer(
        new StringReader(input), preference, expectedColumns);

    try (ICsvBeanReader beanReader = new CsvBeanReader(tokenizer, preference)) {
        String[] header = beanReader.getHeader(true);
        TestBean bean;
        while ((bean = beanReader.read(TestBean.class, header)) != null){
            System.out.println(bean);
        }
        System.out.println(String.format("Ignored lines: %s", tokenizer.getIgnoredLines()));
    }

}

打印以下输出(注意它如何跳过所有无效行):

TestBean{column1='has', column2='three', column3='columns'}
Ignoring line 3 with 2 columns: only,two
Ignoring line 4 with 1 columns: one
TestBean{column1='three', column2='columns', column3='again'}
Ignoring line 6 with 4 columns: one,too,many,columns
Ignored lines: [3, 4, 6]

关于java - 如何使用 supercsv 跳过仅空白的行和具有可变列的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34958724/

相关文章:

java - 启动 spring 批处理作业时将对象作为参数传递

python - 从 CSV 中提取信息

java - 扩展 CustomDialog,edittext 始终为空

java - 如何检查 Vector 是否存在并且已在 Java 中定义?

perl - 解析 CSV 文件和散列

android - 内存不足错误-Android

java - opencsv不导出父类的属性

java - 无法使用 OpenCSV 将 JavaBeans 写入 CSV

java - 使用 OpenCsv 将 CSV 元素映射到字符串列表?

java - 重定向使用和 POST 参数