【问题标题】:How do I skip white-space only lines using Super CSV?如何使用 Super CSV 跳过仅包含空格的行?
【发布时间】:2012-11-27 16:04:09
【问题描述】:

如何配置 Super CSV 以跳过空白行或仅包含空格的行?

我正在使用 CsvListReader,有时我的数据中会出现一个空行。发生这种情况时,会产生以下效果的异常:

CellProcessor 的数量必须与字段的数量相匹配

我想直接跳过这些行。

【问题讨论】:

    标签: java csv supercsv


    【解决方案1】:

    我不知道这个库(您应该添加一个 Java 标记...),但是查看the examples,我看到他们的阅读器支持每行可变数量的行。空行是此模式的子情况。

    或者(可能效率较低),您可以捕获异常并继续阅读...

    【讨论】:

    • 'SuperCSV' 标签是库作者请求的。
    • 这很好,但是你可以添加几个标签,你知道吗? :-) 很高兴您从权威来源得到答案...
    【解决方案2】:

    更新: Super CSV 2.1.0(2013 年 4 月发布)允许您通过首选项提供 CommentMatcher,这样您就可以跳过被视为 cmets 的行。您可以使用 2 个内置匹配器,也可以提供自己的匹配器。在这种情况下,您可以使用new CommentMatches("\\s+") 跳过空白行。


    Super CSV 只跳过零​​长度的行(只是一个行终止符)。

    如果有空行,则不是有效的 CSV 文件(请参阅 RFC4180 的 rule 4 声明 Each line should contain the same number of fields throughout the file)。空行唯一有效的情况是它是由引号包围的多行字段的一部分。例如

    column1,column2
    "multi-line field
    
    with a blank line",value2
    

    话虽如此,有可能让 Super CSV 对空行更宽容一些(它可以忽略它们)。如果您可以在我们的 SourceForge 页面上发布feature request,我们可以对此进行进一步调查,并可能在未来的版本中添加此功能。

    不过现在对你没有帮助!

    我还没有对此进行广泛的测试,但它应该可以工作:) 你可以编写自己的标记器来跳过空行:

    package org.supercsv.io;
    
    import java.io.IOException;
    import java.io.Reader;
    import java.util.List;
    
    import org.supercsv.prefs.CsvPreference;
    
    public class SkipBlankLinesTokenizer extends Tokenizer {
    
        public SkipBlankLinesTokenizer(Reader reader, CsvPreference preferences) {
            super(reader, preferences);
        }
    
        @Override
        public boolean readColumns(List<String> columns) throws IOException {
    
            boolean moreInput = super.readColumns(columns);
    
            // keep reading lines if they're blank
            while (moreInput && (columns.size() == 0 || 
                                 columns.size() == 1 && 
                                 columns.get(0).trim().isEmpty())){
                moreInput = super.readColumns(columns);
            }
    
            return moreInput;
        }
    
    }
    

    只需将其传递给阅读器的构造函数(您必须将首选项传递给阅读器和标记器):

    ICsvListReader listReader = null;
    try {
        CsvPreference prefs = CsvPreference.STANDARD_PREFERENCE;
        listReader = new CsvListReader(
            new SkipBlankLinesTokenizer(new FileReader(CSV_FILENAME), prefs),
            prefs);
    ...
    

    希望对你有帮助

    【讨论】:

    • 好建议!我在线路阅读水平上搞砸了,但这并不正确。我确实不得不稍微修改你的代码。 readColumns() 会解析一列空白,因此 columns.size() == 1。我用我使用的代码更新了你的答案。
    • 嗯...显然我对您的答案的编辑正在等待“同行评审”。这是新的循环条件: (moreInput && columns.size() == 1 && columns.get(0).trim().isEmpty())
    • 好的,我更新了您的编辑以适应空行(columns.size() == 0),就像我原来的答案一样(它对其他人更有用)。我正在考虑改用getUntokenizedRow().trim().isEmpty(),但是在读取制表符分隔的文件时会中断。
    猜你喜欢
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 2019-08-24
    • 2011-09-01
    • 1970-01-01
    • 2018-02-15
    相关资源
    最近更新 更多