我正在尝试获取它,以便我可以更新 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);
}
}
我相信以下就是您所需要的。
(代码后面有注释。)
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;
}
Apache Commons模块。