我想我发现了一个错误.或者可能不是,但Super CSV无法很好地处理.
我正在使用MapReader解析包含41列的CSV文件.但是,我正在获得CSV - 以及给我CSV的网络服务混乱了一行."标题"行是制表符分隔的行,包含41个单元格.
而"错误的行"是一个带有36个单元格的制表符分隔行,内容没有任何意义.
这是我正在使用的代码:
InputStream fis = new FileInputStream(pathToCsv);
InputStreamReader inReader = new InputStreamReader(fis, "ISO-8859-1");
ICsvMapReader mapReader = new CsvMapReader(inReader, new CsvPreference.Builder('"','\t',"\r\n").build());
final String[] headers = mapReader.getHeader(true);
Map<String, String> row;
while( (row = mapReader.read(headers)) != null ) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
我在上面提到的行中执行mapReader.read(headers)时遇到异常.这是例外:
org.supercsv.exception.SuperCsvException:
the nameMapping array and the sourceList should be the same size (nameMapping length = 41, sourceList size = 36)
context=null
at org.supercsv.util.Util.filterListToMap(Util.java:121)
at org.supercsv.io.CsvMapReader.read(CsvMapReader.java:79)
at test.MyClass.readCSV(MyClass.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Run Code Online (Sandbox Code Playgroud)
你觉得我应该怎么做 ?
我不希望整个应用程序崩溃,只是因为一行搞砸了,我宁愿跳过那一行.
这是一个很好的问题!作为Super CSV开发人员,我将研究在网站上创建一些异常处理示例.
您可以保持简单并使用CsvListReader(它不关心有多少列),然后自己创建Map:
public class HandlingExceptions {
private static final String INPUT =
"name\tage\nTom\t25\nAlice\nJim\t44\nMary\t33\tInvalid";
public static void main(String[] args) throws IOException {
// use CsvListReader (can't be sure there's the correct no. of columns)
ICsvListReader listReader = new CsvListReader(new StringReader(INPUT),
new CsvPreference.Builder('"', '\t', "\r\n").build());
final String[] headers = listReader.getHeader(true);
List<String> row = null;
while ((row = listReader.read()) != null) {
if (listReader.length() != headers.length) {
// skip row with invalid number of columns
System.out.println("skipping invalid row: " + row);
continue;
}
// safe to create map now
Map<String, String> rowMap = new HashMap<String, String>();
Util.filterListToMap(rowMap, headers, row);
// do something with your map
System.out.println(rowMap);
}
listReader.close();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
{name=Tom, age=25}
skipping invalid row: [Alice]
{name=Jim, age=44}
skipping invalid row: [Mary, 33, Invalid]
Run Code Online (Sandbox Code Playgroud)
如果你担心使用Super CSV的Util类(它可能会改变它 - 它实际上是一个内部实用程序类),你可以像我在这里建议的那样组合2个读者.
您可以尝试捕获SuperCsvException,但最终可能会抑制不仅仅是无效的列数.我建议捕获的唯一超级CSV异常(虽然不适用于您未使用单元处理器的情况)SuperCsvConstraintViolationException,因为它表示文件格式正确,但数据不满足您的预期约束.