大家好!我的目标是让csv阅读器在解析文件时跳过空行,基本上什么都不做,只得到至少有一个值的行。目前我有两个方法-〉第一个方法是将所有行读取为字符串列表数组并返回,第二个方法将结果转换为字符串列表列表,两个方法都如下:
private List<String[]> readCSVFile(File filename) throws IOException {
CSVReader reader = new CSVReader(new FileReader(filename));
List<String[]> allRows = reader.readAll();
return allRows;
}
public List<List<String>> readFile(File filename) throws IOException {
List<String[]> allRows = readCSVFile(filename);
List<List<String>> allRowsAsLists = new ArrayList<List<String>>();
for (String[] rowItemsArray : allRows) {
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
return allRowsAsLists;
}
我的第一个想法是检查(在第二个方法中)数组的长度,如果它是0,就忽略它--这将是这样的:
for (String[] rowItemsArray : allRows) {
**if(rowItemArray.length == 0) continue;**
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
不幸的是,这并不起作用,因为即使行是空的,它仍然返回一个元素数组-实际上是空字符串。检查单个字符串不是一个选项,因为有100+列,这是可变的。请建议什么是最好的方法来实现这一点。谢谢。
我是这么想的:
public List<List<String>> readFile(File filename) throws IOException {
List<String[]> allRows = readCSVFile(filename, includeHeaders, trimWhitespacesInFieldValues);
List<List<String>> allRowsAsLists = new ArrayList<List<String>>();
for (String[] rowItemsArray : allRows) {
**if(allValuesInRowAreEmpty(rowItemsArray)) continue;**
List<String> rowItems = new ArrayList<String>();
rowItems.addAll(Arrays.asList(rowItemsArray));
allRowsAsLists.add(rowItems);
}
return allRowsAsLists;
}
private boolean allValuesInRowAreEmpty(String[] row) {
boolean returnValue = true;
for (String s : row) {
if (s.length() != 0) {
returnValue = false;
}
}
return returnValue;
}
8条答案
按热度按时间2hh7jdfx1#
您可以检查长度和第一个元素。如果行只包含字段分隔符,则长度〉1。如果行包含单个
space
字符,则第一个元素不为空。b4wnujal2#
对于opencsv 5.0,有一个API选项可以将CSV行直接读入Bean。
对于喜欢使用“CsvToBean”特性的人,下面的解决方案使用CsvToBeanBuilder上的#withFilter(..)方法(可惜已弃用)跳过输入流中的空行:
更新:在opencsv发布版本5.1(日期为2020年2月2日)中,根据功能请求#120,CsvToBeanFilter未被删除。
unguejic3#
以下是基于@Martin的solution的lambdas更新解决方案:
bd1hkmkf4#
您可以使用带有lambda的过滤器:如下所示:
您的lambda过滤器:
gr8qqesn5#
您可以在修剪字符串值后汇总每行的所有字符串值。如果生成的字符串为空,则任何单元格中都没有值。在这种情况下,忽略该行。
大概是这样的
wecizke36#
如果不解析为Bean,可以使用Java Streams API来帮助过滤无效的CSV行。我的方法如下(其中
is
是包含CSV数据的java.io.InputStream
示例,YourBean map(String[] row)
是将CSV行Map到Java对象的Map方法:vu8f3i0k7#
JavaDoc for CsvToBeanFilter声明“以下示例显示了如何使用CsvToBean来删除空行。因为解析器返回一个数组,其中包含一个用于检查空行的空字符串。”并列出了如何执行此操作的示例:
u1ehiz5o8#
另一种方法是重写类
CsvToBeanFilter
的allowLine()
方法,并在构建bean时将其传递给.withFilter()
(Kotlin中的示例也适用于Java):