在 OPENcsv Java 中写入单个单元格

问题描述 投票:0回答:1

我正在尝试获取它,以便我可以更新 csv 中的一个值。数据结构为{姓名,分数}。给定一个名称,我想将分数增加 1。我有 POJO 和所有设置来获取所需的信息,但我的问题是,当我尝试写入文件时,它会覆盖所有内容或不覆盖任何内容。我已经测试了我的阅读,以确保它正确地获得了正确的名称,并且似乎做到了这一点。所以我想弄清楚如何修复写入功能。

      public static void updateCounter(String name){
        int score = 0;

        ArrayList<String> namesArray = new ArrayList<>();
        CSVParser parser = new CSVParserBuilder()
                .withSeparator(',')
                .withIgnoreQuotations(true)
                .build();

        try (Writer writer  = new FileWriter("output.txt",true)) {
            ColumnPositionMappingStrategy<Person> strategy = new ColumnPositionMappingStrategy<Person>();
            StatefulBeanToCsv<Person> sbc = new StatefulBeanToCsvBuilder<Person>(writer)
                    .withSeparator(CSVWriter.DEFAULT_SEPARATOR)
                    .withMappingStrategy(strategy)
                    .build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        List<Person> beans;
        try {
            beans = new CsvToBeanBuilder<Person>(new FileReader("data.csv"))
                    .withType(Person.class)
                    .build()
                    .parse();
            for(Person p : beans){
                if(p.getName().equals(name)){
                    score = score = p.getscore() + 1;
                }
            }
            CSVReader reader;
            {
                try {
                    String[] line;
                    reader = new CSVReader(new FileReader("data.csv"));
                    {
                        try {
                            while ((line = reader.readNext()) != null) {
                                for (String cell : line) {
                                    if(cell.equals(name)){
                                        BufferedWriter writer;
                                        {
                                            try {
                                                writer = new BufferedWriter(new FileWriter("data.csv"));

                                                writer.write(score);
                                                writer.close();
                                            } catch (IOException IOerr) {
                                                throw new RuntimeException(IOerr);
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (CsvException ex) {
                            throw new RuntimeException(ex);
                        }
                        reader.close();
                    }
                } catch (IOException IOerr) {
                    throw new RuntimeException(IOerr);
                }
            }
        } catch (FileNotFoundException ex) {
            throw new RuntimeException(ex);
        }
    }
java opencsv
1个回答
0
投票

我相信以下就是您所需要的。
(代码后面有注释。)

import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.CsvToBeanBuilder;

import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

public class Person {

    @CsvBindByName
    private String  name;

    @CsvBindByName
    private int score;

    public Person() {
        this(null, 0);
    }

    public Person(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

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

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public String toString() {
        return String.format("%s,%d", name, score);
    }

    public static void main(String[] args) {
        try {
            List<Person> beans = new CsvToBeanBuilder<Person>(new FileReader("data.csv")).withType(Person.class)
                                                                                         .build()
                                                                                         .parse();
            for (Person p : beans) {
                System.out.println(p);
                if ("George".equals(p.getName())) {
                    p.setScore(p.getScore() + 1);
                }
            }
            Path path = Paths.get("data.csv");
            try (BufferedWriter bw = Files.newBufferedWriter(path,
                                                             StandardOpenOption.TRUNCATE_EXISTING,
                                                             StandardOpenOption.WRITE)) {
                bw.write("name,score");
                bw.newLine();
                for (Person p : beans) {
                    String line = String.format("%s,%d%n", p.getName(), p.getScore());
                    bw.write(line);
                }
            }
        }
        catch (IOException x) {
            x.printStackTrace();
        }
    }
}

为了让

CsvToBeanBuilder
工作,
Person
需要是一个 JavaBeans 类,这意味着它需要一个无参数构造函数。然而,这会给你一个
List
,其中
Person
中的每个
List
对象都将具有 null
name
和 0(零)
score

为了克服这个问题并使用文件

Person
中的数据实例化类
data.csv
,您可以使用
CsvBindByName
注释。请参阅文档

创建

List
后,上面的代码会更新它。为了演示,我只是使用了一个硬编码值,即George

最后,更新

List
后,我用更新后的
data.csv
的内容覆盖文件
List
。我使用 NIO.2 来实现这一点。

请注意,如果文件

data.csv
太大而无法完全加载到计算机内存中,则上述代码可能无法工作。

这是我使用的示例

data.csv
文件:

name,score
George,11
Diego,10
Franz,5
Johan,8

如文档中所述,需要“标题”行才能使

CsvBindByName
注释发挥作用。

以上是使用 Eclipse 2024-09 在 Windows 10 上使用 Java 21 开发的。

这是我需要的

module-info.java

module opencsvm {
    opens opencsvp;
    requires com.opencsv;
    requires org.apache.commons.collections4;
    requires org.apache.commons.lang3;
    requires commons.beanutils;
    requires java.sql;
    requires org.apache.commons.logging;
}

CsvToBeanBuilder需要

Apache Commons
模块。

© www.soinside.com 2019 - 2024. All rights reserved.