如何使用supercsv跳过仅限空格的行和具有可变列的行

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

我想忽略只有空格的行和包含少于25列的行。

我正在使用IcvBeanReader和名称映射(将csv值设置为pojo)和字段处理器(以处理validation)来读取文件。

我假设Supercsv IcvBeanReader默认会跳过空白行。 但如果一行包含少于25个列号,如何处理?

您可以通过编写自己的Tokenizer轻松完成此操作。

例如,以下Tokenizer将具有与默认Tokenizer相同的行为,但将跳过任何没有正确列数的行。

public class SkipBadColumnCountTokenizer extends Tokenizer { private final int expectedColumns; private final List ignoredLines = new ArrayList<>(); public SkipBadColumnCountTokenizer(Reader reader, CsvPreference preferences, int expectedColumns) { super(reader, preferences); this.expectedColumns = expectedColumns; } @Override public boolean readColumns(List 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 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] 

(1)如果您的Java程序必须使用Super CSV ,那么(我引用)“您将不得不使用CsvListReader”。 特别是:listReader.length()

有关详细信息,请参阅此超级CSV页面

(2)如果您可以通过预处理CSV文件来执行选择,那么您可能希望考虑使用合适的命令行工具(或工具,具体取决于CSV格式的复杂程度)。 如果CSV文件的分隔符不在任何字段中出现,那么awk就足够了。 例如,如果满足假设,并且分隔符是| ,那么相关的awkfilter可以很简单:

 awk -F'|' 'NF == 25 {print}' 

如果CSV文件格式对于awk的天真应用而言过于复杂,那么您可能希望将复杂格式转换为更简单的格式; 通常TSV有很多值得推荐的。