首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用jackson-dataformat-csv解析CSV时跳过几个初始行?

如何在使用jackson-dataformat-csv解析CSV时跳过几个初始行?
EN

Stack Overflow用户
提问于 2017-04-24 09:37:11
回答 4查看 6.8K关注 0票数 1

我有以下格式的CSV:

代码语言:javascript
复制
New CSV file

header_1,header_2,header_3,header_4
value_1,value_2,value_3,value_4
value_1,value_2,value_3,value_4
value_1,value_2,value_3,value_4

我有下面的代码来解析这个CSV:

代码语言:javascript
复制
    CsvMapper csvMapper = new CsvMapper();
    CsvSchema schema = CsvSchema.emptySchema().withSkipFirstDataRow(true);
    List<CsvModel> rows = new LinkedList<>();
    MappingIterator<CsvModel> iterator = csvMapper
            .readerFor(CsvModel.class).with(schema)
            .readValues(filePath.toFile());
    while (iterator.hasNext()) {
        CsvModel csvElement = iterator.next();
        if (StringUtils.isBlank(csvElement.getValue1())) {
            // skip lines not having the value
            continue;
        }
        rows.add(csvElement);
    }

但是,在解析上面提到的CSV格式文件时,我得到了以下异常:

代码语言:javascript
复制
com.fasterxml.jackson.databind.RuntimeJsonMappingException: Can not construct instance of com.adapters.CsvParsing: no String-argument constructor/factory method to deserialize from String value ('')
 at [Source: com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader@2cb566f1; line: 2, column: 1]

这是因为第二行是空的。我需要跳过前两行,如何告诉jackson跳过文件的前两行?

编辑1:这里是CsvModel文件:

代码语言:javascript
复制
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class CsvModel {
    public static final String IdField = "Id";
    public static final String NameField = "Name";
    public static final String GuidField = "Guid";
    public static final String SubscriptionNameField = "Subscription Name";
    public static final String DateField = "Date";
    public static final String CostField = "Cost";

    @JsonProperty(IdField)
    private String Id;
    @JsonProperty(NameField)
    private String Name;
    @JsonProperty(GuidField)
    private String Guid;
    @JsonProperty(SubscriptionNameField)
    private String SubscriptionName;
    @JsonProperty(DateField)
    private String Date;
    private Long epochDate;
    @JsonProperty(CostField)
    private Double Cost;

    public String getId() {
        return this.Id;
    }

    public void setId(String id) {
        this.Id = id;
    }

    public String getName() {
        return this.Name;
    }

    public void setName(String name) {
        this.Name = name;
    }

    public String getGuid() {
        return this.Guid;
    }

    public void setGuid(String guid) {
        this.Guid = guid;
    }

    public String getSubscriptionName() {
        return this.SubscriptionName;
    }

    public void setSubscriptionName(String subscriptionName) {
        this.SubscriptionName = subscriptionName;
    }

    public String getDate() {
        return this.Date;
    }

    public void setDate(String date) {
        this.Date = date;
    }

    public Long getEpochDate() {
        return this.epochDate;
    }

    public void setEpochDate(Long epochDate) {
        this.epochDate = epochDate;
    }

    public Double getCost() {
        return this.Cost;
    }

    public void setCost(Double cost) {
        this.Cost = cost;
    }
}
EN

回答 4

Stack Overflow用户

发布于 2020-03-29 21:36:30

要跳过空行,可以使用SKIP_EMPTY_LINES特性:

代码语言:javascript
复制
CsvMapper csvMapper = new CsvMapper().enable(CsvParser.Feature.SKIP_EMPTY_LINES);

CsvSchema schema = csvMapper.emptySchema().withSkipFirstDataRow(true);
MappingIterator<Account> dataIterator = csvMapper.readerFor(CsvModel.class).with(schema)
    .readValues(file);
票数 4
EN

Stack Overflow用户

发布于 2017-04-24 09:41:32

您可以跳过前两行,方法是在处理前两次推进迭代器,例如:

代码语言:javascript
复制
for(int i=0 ; i<2 ; i++){
    if(iterator.hasNext()){
        iterator.next();
    }
}

while (iterator.hasNext()) {
...

这将确保如果文件少于2条记录,则不会引发任何Exception

更新

根据问题编辑编辑答案:

它抛出RuntimeJsonMappingException的原因是因为它将vsc文件的一行解释为字符串,并试图将String绑定到CsvModel对象。您需要使用schema映射器指定一个(非空的) csvMapper映射器,该映射器在反序列化一行时充当metadata,例如:

代码语言:javascript
复制
CsvSchema schema = CsvSchema.builder()
        .setColumnSeparator(',')
        .addColumn("Id")
        .addColumn("name")
        ....

您可以查看示例。

票数 1
EN

Stack Overflow用户

发布于 2020-02-24 07:09:37

一个更好的解决方案是使用BufferedReader.readLine()使用前几行。

请参阅此跳过行

样本代码:

代码语言:javascript
复制
try (final BufferedReader reader = new BufferedReader(new FileReader(csvFile))) {
  // consume the first few lines here
  reader.readLine();
  reader.readLine();

  final MappingIterator<MyClass> readValues =
    new CsvMapper()
         .readerFor(MyClass.class)
         .with(emptySchema()
                .withHeader()
                .withNullValue(""))
         .readValues(reader);

  final List<MyClass> records = readValues.readAll();
} catch (Exception e) {
  log.warn("Failed to read detail section of transactionItem file.");
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43584628

复制
相关文章

相似问题

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