java - 使用 SuperCSV CSVBeanReader 时在字符串上使用什么单元处理器

标签 java csv supercsv

@Carl V. Dango,@Zsolt,@Jon, 让我们重新开始。这是我的代码和错误(在底部)。您会在控制台输出中注意到前两行原始数据。第一行中的第一个字段(“item”)在输出中为空。我认为它应该是 'xx' 因为我在该列上编码了 StrReplace("","xx") 。我更担心的是如何在第三条记录的第 4 列中捕获空值/空白。这些看起来很基础,我有点沮丧,要解决这么麻烦。

package com.mycompany.data.transfers.app;

import java.io.FileReader;

import org.supercsv.cellprocessor.ConvertNullTo;
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.prefs.CsvPreference;

import com.mycompany.data.transfers.models.Invoice;

public class Test {

/**
 * @param args
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {

    char quote = '"';
    int delimeter = 124;
    String newLine = "\n";

    CellProcessor[] cp = new CellProcessor[] { 
            new StrReplace(" ", "xx"),
            null,
            new ParseDate("yyyyMMdd"), 
            new ParseBigDecimal(),
            new ConvertNullTo("0", new ParseBigDecimal()),
            new ParseDate("yyyyMMdd"), 
            null,
            new ParseDate("yyyyMMdd"), 
            null,
            null,
            null,
            null,
            null,
            new ParseInt() 
        };

    Invoice bean = new Invoice();

    CsvBeanReader inFile = new CsvBeanReader(new FileReader("c:\\temp\\my_test_file.txt"), new CsvPreference(quote, delimeter, newLine));

    while ((bean = inFile.read(bean.getClass(), new String[] {"item", "loc", "schedDate", "fracQty", "recQty",
        "expDate", "poNum", "dateShip", "masterLoadId", "loadId",
        "confirmationNumber", "sourceWarehouse", "purchasingGroup",
        "poDistFlag" }, cp)) != null) {
        System.out.println(bean);
    }
}

Invoice [item=, loc=NEW, schedDate=Wed Nov 02 00:00:00 CDT 2011, fracQty=5, recQty=4]
Invoice [item=0006268410, loc=SHR, schedDate=Thu Nov 03 00:00:00 CDT 2011, fracQty=12, recQty=5]
Exception in thread "main" null
Parser error context: Line: 3 Column: 4 Raw line:
[0000939515, NEW, 20111102, 50, , 20111102, , 20111102, 0000000000, 0000000000, , , BBA, 1]
 offending processor: org.supercsv.cellprocessor.ParseBigDecimal@17a8913
at org.supercsv.cellprocessor.ParseBigDecimal.execute(Unknown Source)
at org.supercsv.cellprocessor.ConvertNullTo.execute(Unknown Source)
at org.supercsv.util.Util.processStringList(Unknown Source)
at org.supercsv.io.CsvBeanReader.read(Unknown Source)
at com.mycompany.data.transfers.app.Test.main(Test.java:48)
Caused by: java.lang.NumberFormatException
at java.math.BigDecimal.<init>(BigDecimal.java:534)
at java.math.BigDecimal.<init>(BigDecimal.java:728)
... 5 more

最佳答案

这里的问题是 CsvBeanReader 不会将空列转换为 null,而是转换为 ""(空字符串)。因此,您应该只在编写 CSV 文件时真正需要ConvertNullTo 处理器。

所以代替

new ConvertNullTo("0", new ParseBigDecimal())

你应该使用

new Token("", "0", new ParseBigDecimal()) // replace "" with "0"

这是假设您想要一个 BigDecimal,空白列的值为零 - 如果您希望它为 null 而不是使用

new Optional(new ParseBigDecimal())

我承认站点和 javadoc 需要使这一点更加明确,这是我正在为即将发布的 Super CSV 所做的工作。


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

最近发布的 Super CSV 2.0.0-beta-1 包括许多错误修复和新功能(包括 Maven 支持和用于映射嵌套属性和数组/集合的新 Dozer 扩展)。它还更改了对空值和空字符串的处理。

新版本将 ""(空列)读作 null,这意味着您现在可以使用您的原始代码:

new ConvertNullTo("0", new ParseBigDecimal())

因此,Optional() 单元处理器现在匹配 null 而不是 "",这意味着您还可以写入时将其用作单元处理器(null 值现在将被写入为 "")。

关于java - 使用 SuperCSV CSVBeanReader 时在字符串上使用什么单元处理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8307320/

相关文章:

java - 关于相同/不同对象上的 java 线程的混淆

java - Groovy 从集合中删除值

java - log4j linux 问题 - 日志文件为空

python csv扭曲告诉

java - 在 Groovy 中使用参数动态创建方法

java - 使用 super-CSV 读取嵌套 POJO

java - 如何使用 Super CSV 将列表写入 CSV

java - JButton 的操作监听器不起作用

python - 使用嵌套 for 和 if 循环时加快 Python 速度

java - 带有 IntelliJ 的 opencsv