@Carlo V. Dango 我已经简化了我的问题,我已经阅读了文档 - 不要惊慌的好建议。不过,我有问题。帮助我解决一个,它将解决所有问题。谢谢。
问题:当我有一个缺少非String字段的csv记录时,如何(甚至可以)将缺失的条目转换为默认值,或者至少不抛出NullPointerException?可选的cellProcessor似乎也不会阻止错误。
该计划主要来自SuperCSV网站。
package com.test.csv;
import java.io.FileReader;
import org.supercsv.cellprocessor.ParseBigDecimal;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
public class CSVReader {
private static final CellProcessor[] cellProcessor = new CellProcessor[] {
null,
null,
new ParseInt(),
new ParseDate("yyyyMMdd"),
new ParseBigDecimal()
};
public static void main (String[] args ) throws Exception {
CsvPreference pref = new CsvPreference('"', '|', "\n");
ICsvBeanReader inFile = new CsvBeanReader(new FileReader("C:\\temp\\sapfilePipe.txt"), pref);
try {
final String[] header = inFile.getCSVHeader(true);
User user;
while ((user = inFile.read(User.class, header, cellProcessor)) != null) {
System.out.println(user);
}
} finally {
inFile.close();
}
}
}
这是我正在阅读的CSV文件。请注意,在第一条记录中有一个缺失的字段(年龄)。
firstName|lastName|age|hireDate|hourlyRate
A.|Smith| |20110101|15.50
我的用户bean:
package com.test.csv;
import java.math.BigDecimal;
import java.util.Date;
public class User {
private String firstName;
private String lastName;
private int age;
private Date hireDate;
private BigDecimal hourlyRate;
...getters/setters...
这是错误:
Exception in thread "main" java.lang.NullPointerException
at org.supercsv.io.CsvBeanReader.fillObject(Unknown Source)
at org.supercsv.io.CsvBeanReader.read(Unknown Source)
at com.glazers.csv.CSVReader.main(CSVReader.java:31)
感谢。
答案 0 :(得分:3)
修改:[{3}}
的更新Super CSV 2.0.0-beta-1现已推出。它包含许多错误修复和新功能(包括Maven支持和用于映射嵌套属性和数组/集合的新Dozer扩展)。
它还改变了处理空(""
)列的方式 - 它们现在被读作null
。
这意味着,如果CSV文件中不存在,则bean中的firstName
和lastName
字段现在将为null
而不是""
。
Optional()
处理器已更新以满足此要求 - 因此它仍将以相同的方式运行。
我建议使用Token
不再相关:您应该使用ConvertNullTo
代替:
new ConvertNullTo(-1, new ParseInt())
真正想要的是Optional
CellProcessor,如果列不为空,它只允许链中的下一个处理器执行。
因此,将CellProcessor数组更新为:
private static final CellProcessor[] cellProcessor = new CellProcessor[] {
null,
null,
new Optional(new ParseInt()),
new ParseDate("yyyyMMdd"),
new ParseBigDecimal()
};
这样,只有当列不为空(CellProcessors从左到右执行)时才会执行ParseInt
,将bean中的int字段保留为默认值0。
如果要将字段设置为-1表示没有提供任何值,则可以使用Token
处理器,它将使用所需值替换任何令牌(在本例中为“”),对于任何其他输入,它将继续到下一个处理器。即。
new Token("", -1, new ParseInt())
@Carlo V. Dango CsvListReader是一个非常原始的实现(并且你失去了映射到bean的能力)所以我只会用它来进行快速和脏的解析。
我只建议在数组中使用null
(在阅读时),不需要进一步处理的字符串属性。
顺便说一下,我正在为即将发布的版本工作的Super CSV项目。我一定会在网站上改进代码示例;)
答案 1 :(得分:1)
列表阅读器将每一行读入字符串列表。看来这就是你要找的东西。
http://supercsv.sourceforge.net/javadoc/org/supercsv/io/CsvListReader.html
或如此处所示http://supercsv.sourceforge.net/codeExamples_general.html如果您不想要任何具体的操作,可以将处理器设置为null。