首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析SuperCSV中的字符串

解析SuperCSV中的字符串
EN

Stack Overflow用户
提问于 2011-11-28 07:09:16
回答 2查看 8.3K关注 0票数 2

@Carlo V.Dango我已经简化了我的问题,并且我已经阅读了文档--这是一个不要惊慌的好建议。尽管如此,我还是有问题。帮我解决一个问题,它就能解决所有问题。谢谢。

问:当我的csv记录缺少非字符串字段时,如何(甚至可以)将缺少的条目转换为默认值,或者至少不抛出NullPointerException?可选的cellProcessor似乎也不能防止错误。

这是从SuperCSV网站上摘录的程序。

代码语言:javascript
复制
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文件。请注意,第一条记录中缺少一个字段(age)。

代码语言:javascript
复制
firstName|lastName|age|hireDate|hourlyRate
A.|Smith|  |20110101|15.50

我的用户bean:

代码语言:javascript
复制
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...   

下面是错误:

代码语言:javascript
复制
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)

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-28 20:06:44

列表读取器将每一行读入一个字符串列表。看起来这就是你要找的。

http://super-csv.github.io/super-csv/apidocs/org/supercsv/io/CsvListReader.html

或者,如这里所示,http://super-csv.github.io/super-csv/examples_reading.html如果您不想做任何特定的事情,可以将处理器设置为null。

票数 1
EN

Stack Overflow用户

发布于 2012-02-12 20:59:37

编辑:Super CSV 2.0.0-beta-1更新

Super CSV 2.0.0-beta-1现已发布。它包括许多bug修复和新特性(包括Maven支持和一个新的Dozer扩展,用于映射嵌套属性和数组/集合)。

它还改变了处理空列("")的方式--它们现在被读取为null。这意味着如果您的bean中的firstNamelastName字段没有出现在CSV文件中,那么它们现在将是null而不是""

Optional()处理器已经针对这一点进行了更新-因此它仍将以相同的方式工作。

我关于使用Token的建议不再重要:您应该改用ConvertNullTo

代码语言:javascript
复制
new ConvertNullTo(-1, new ParseInt())

您真正想要的是Optional CellProcessor,它只允许链中的下一个处理器在列不为空的情况下执行。

因此,请将CellProcessor数组更新为:

代码语言:javascript
复制
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处理器,它将用所需的值替换任何标记(在本例中为“”),对于任何其他输入,它将继续到下一个处理器。即

代码语言:javascript
复制
new Token("", -1, new ParseInt())

@Carlo V.Dango CsvListReader是一个非常原始的实现(并且您失去了映射到beans的能力),所以我只会将其用于快速和肮脏的解析。

对于不需要进一步处理的字符串属性,我建议只在数组中使用null (在读取时)。

顺便说一句,我是Super CSV项目的一员,正在为即将发布的版本工作。在此期间,我一定会改进网站上的代码示例;)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8289855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档