【发布时间】:2014-06-26 16:28:35
【问题描述】:
我正在尝试将具有宠物列表的人员类持久保存到 CSV 文件中,并将其读回相应的对象。我能够正确地写它但无法阅读。请看下面-
Person.java
import java.util.ArrayList;
import java.util.List;
public class Person {
private String name;
private List<Pet> pets;
public Person() {
}
public Person(final String name, final List<Pet> pets) {
this.name = name;
this.pets = pets;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the pets
*/
public List<Pet> getPets() {
return pets;
}
/**
* @param pets
* the pets to set
*/
public void setAddPet(final Pet pet) {
if (pets == null) {
pets = new ArrayList<Pet>();
}
pets.add(pet);
}
/**
* @param name
* the name to set
*/
public void setName(final String name) {
this.name = name;
}
/**
* @param pets
* the pets to set
*/
public void setPets(final List<Pet> pets) {
this.pets = pets;
}
@Override
public String toString() {
return String.format("Person [name=%s, pets=%s]", name, pets);
}
}
Pet.java
public class Pet {
private String typeOfAnimal;
private String color;
public Pet() {
}
public Pet(final String typeOfAnimal, final String color) {
this.typeOfAnimal = typeOfAnimal;
this.color = color;
}
/**
* @return the color
*/
public String getColor() {
return color;
}
/**
* @return the typeOfAnimal
*/
public String getTypeOfAnimal() {
return typeOfAnimal;
}
/**
* @param color
* the color to set
*/
public void setColor(final String color) {
this.color = color;
}
/**
* @param typeOfAnimal
* the typeOfAnimal to set
*/
public void setTypeOfAnimal(final String typeOfAnimal) {
this.typeOfAnimal = typeOfAnimal;
}
@Override
public String toString() {
return String.format("Pet [typeOfAnimal=%s, color=%s]", typeOfAnimal, color);
}
}
Writer.java
import java.io.FileWriter;
import java.util.Arrays;
import java.util.List;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.dozer.CsvDozerBeanWriter;
import org.supercsv.io.dozer.ICsvDozerBeanWriter;
import org.supercsv.prefs.CsvPreference;
public class Writer {
private static final String[] HEADERS = new String[] { "name", "pets" };
private static final CellProcessor[] processors = new CellProcessor[] { new NotNull(),
new NotNull() };
private static final String CSV_FILENAME = "C:\\Users\\Desktop\\Test.csv";
public static void writeWithDozerCsvBeanWriter() throws Exception {
// create the survey responses to write
final Person person1 = new Person("Dereck", Arrays.asList(new Pet("Dog",
"Black")));
final Person person2 =
new Person("Gavin", Arrays.asList(new Pet("Squirrel", "Brown"), new Pet("Cat",
"White")));
final List<Person> people = Arrays.asList(person1, person2);
ICsvDozerBeanWriter beanWriter = null;
try {
beanWriter =
new CsvDozerBeanWriter(new FileWriter(CSV_FILENAME),
CsvPreference.STANDARD_PREFERENCE);
// configure the mapping from the fields to the CSV columns
beanWriter.configureBeanMapping(Person.class, HEADERS);
// write the header
beanWriter.writeHeader(HEADERS);
// write the beans
for (final Person person : people) {
beanWriter.write(person, processors);
}
} finally {
if (beanWriter != null) {
beanWriter.close();
}
}
}
}
Reader.java
import java.io.FileReader;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
public class Reader {
private static final String CSV_FILENAME = "C:\\Users\\Desktop\\Test.csv";
/**
* An example of reading using CsvBeanReader.
*/
public static void readWithCsvBeanReader() throws Exception {
ICsvBeanReader beanReader = null;
try {
beanReader =
new CsvBeanReader(new FileReader(CSV_FILENAME),
CsvPreference.STANDARD_PREFERENCE);
// the header elements are used to map the values to the bean (names must
match)
final String[] header = beanReader.getHeader(true);
// set up the field mapping and processors dynamically
final String[] fieldMapping = new String[header.length];
final CellProcessor[] processors = new CellProcessor[header.length];
for (int i = 0; i < header.length; i++) {
if (i < 1) {
// normal mappings
fieldMapping[i] = header[i];
processors[i] = new NotNull();
} else {
// attribute mappings
fieldMapping[i] = "AddPet";
processors[i] = new Optional(new ParsePersonPet(header));
}
}
Person person;
while ((person = beanReader.read(Person.class, fieldMapping, processors)) !=
null) {
System.out.println(String.format("person=%s", person));
}
} finally {
if (beanReader != null) {
beanReader.close();
}
}
}
}
ParsePersonPet.java
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.util.CsvContext;
public class ParsePersonPet extends CellProcessorAdaptor {
private final String[] header;
public ParsePersonPet(final String[] header) {
this.header = header;
}
@Override
public Object execute(final Object value, final CsvContext context) {
if (value == null) {
return null;
}
final Pet pet = new Pet();
pet.setTypeOfAnimal((String) value);
return pet;
}
}
目前,它正在写入 csv,如下所示 -
但是当我读回来并打印它时,它会打印如下 -
person=Person [name=Dereck, pets=[Pet [typeOfAnimal=[Pet [typeOfAnimal=Dog,
color=Black]], color=null]]]
person=Person [name=Gavin, pets=[Pet [typeOfAnimal=[Pet [typeOfAnimal=Squirrel,
color=Brown], Pet [typeOfAnimal=Cat, color=White]], color=null]]]
我知道问题出在 ParsePersonPet.java 处
pet.setTypeOfAnimal((String) value);
但该值似乎以 Pet [typeOfAnimal=Dog, color=Black] 的字符串形式返回,我是否必须使用 String Tokenizer 并设置适当的值?这可能很乏味吧?我在这里做什么?
谢谢
更新:我通过将 ParsePersonPet 更改为下面的代码来工作 -
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.util.CsvContext;
public class ParsePersonPet extends CellProcessorAdaptor {
private final String[] header;
public ParsePersonPet(final String[] header) {
this.header = header;
}
@Override
public Object execute(final Object value, final CsvContext context) {
if (value == null) {
return null;
}
final String str = (String) value;
final Pet pet = new Pet();
pet.setTypeOfAnimal(getValue("typeOfAnimal", str));
pet.setColor(getValue("color", str));
return pet;
}
public String getValue(final String strValueToSearchFor, final String str) {
if (str.contains(strValueToSearchFor)) {
final int startIndex =
str.lastIndexOf(strValueToSearchFor) + strValueToSearchFor.length() + 1;
int endIndex = str.indexOf(",", startIndex);
if (endIndex == -1) {
endIndex = str.indexOf("]", startIndex);
}
return str.substring(startIndex, endIndex);
}
return null;
}
}
我需要知道如何避免使用 setAddpet 并改用 setPets 以及如果我有宠物地图而不是列表该怎么办。
谢谢
【问题讨论】: