在我的应用程序中,我使用了很多CSV文件,我必须阅读它们并根据它们构建列表.我想发现一个简单的方法来做到这一点.你知道任何简单的框架,它没有使用配置文件的数量等吗?
例如,我有一个人类:
public class Person {
String name;
String surname;
double shoeSize;
boolean sex; // true: male, false:female
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public double getShoeSize() {
return shoeSize;
}
public void setShoeSize(double shoeSize) {
this.shoeSize = shoeSize;
}
public boolean isSe) {
return sex;
}
public void setSeboolean sex) {
this.sex = sex;
}
Run Code Online (Sandbox Code Playgroud)
}
对于本课程,我准备了CSV文件:
name,surname,shoesize,sex
Tom,Tommy,32,true
Anna,Anny,27,false
Run Code Online (Sandbox Code Playgroud)
我怎么能轻易做到?
Asa*_*saf 11
读取和序列化数据的最简单方法之一是使用 Jackson 库。它还有一个 CSV 扩展,你可以在这里找到 wiki
假设你有一个这样的 Pojo:
@JsonPropertyOrder({ "name", "surname", "shoesize", "gender" })
public class Person {
public String name;
public String surname;
public int shoesize;
public String gender;
}
Run Code Online (Sandbox Code Playgroud)
和这样的 CSV:
Tom,Tommy,32,m
Anna,Anny,27,f
Run Code Online (Sandbox Code Playgroud)
然后阅读它是这样完成的:
MappingIterator<Person> personIter = new CsvMapper().readerWithTypedSchemaFor(Person.class).readValues(csvFile);
List<Person> people = personIter.readAll();
Run Code Online (Sandbox Code Playgroud)
This is simple enough for my taste, basically all you need to do is add the column order in your CSV file using the @JsonPropertyOrder annotation and then just read the file using the above 2 lines.
有很多用 Java 编写的优秀框架可以解析 CSV 文件并形成对象列表。OpenCSV、JSefa和jCSV仅举几例。
对于您的要求,我相信jCSV最适合。下面是 jCSV 中的示例代码,您可以轻松使用它们。
Reader reader = new FileReader("persons.csv");
CSVReader<Person> csvPersonReader = ...;
// read all entries at once
List<Person> persons = csvPersonReader.readAll();
// read each entry individually
Iterator<Person> it = csvPersonReader.iterator();
while (it.hasNext()) {
Person p = it.next();
// ...
}
Run Code Online (Sandbox Code Playgroud)
而且,解析一个CSV文件并把它转换成一个List也没什么大不了的,不用任何框架就可以实现,如下图。
br = new BufferedReader(new FileReader(csvFileToRead));
List<Person> personList = new ArrayList<>();
while ((line = br.readLine()) != null) {
// split on comma(',')
String[] personCsv = line.split(splitBy);
// create car object to store values
Person personObj = new Person();
// add values from csv to car object
personObj.setName(personCsv[0]);
personObj.setSurname(personCsv[1]);
personObj.setShoeSize(personCsv[2]);
personObj.setGender(personCsv[3]);
// adding car objects to a list
personList.add(personObj);
}
Run Code Online (Sandbox Code Playgroud)
如果 CSV 列到 bean 对象的映射在实际情况下很复杂、重复或很大,那么可以使用DozerBeanMapper轻松完成。
希望这会帮助你。
石狮
不确定您是否需要使用外部库(并采取通常隐含的性能损失)。实现起来是一件非常简单的事情。如果不出意外,了解这样一个库中幕后发生的事情总是有帮助的:
public List<Person> readFile(String fileName) throws IOException {
List<Person> result = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));
try {
// Read first line
String line = br.readLine();
// Make sure file has correct headers
if (line==null) throw new IllegalArgumentException("File is empty");
if (!line.equals("name,surname,shoesize,sex"))
throw new IllegalArgumentException("File has wrong columns: "+line);
// Run through following lines
while ((line = br.readLine()) != null) {
// Break line into entries using comma
String[] items = line.split(",");
try {
// If there are too many entries, throw a dummy exception, if
// there are too few, the same exception will be thrown later
if (items.length>4) throw new ArrayIndexOutOfBoundsException();
// Convert data to person record
Person person = new Person();
person.setName ( items[0] );
person.setSurname ( items[1] );
person.setShoeSize(Double .parseDouble (items[2]));
person.setSex (Boolean.parseBoolean(items[3]));
result.add(person);
} catch (ArrayIndexOutOfBoundsException|NumberFormatException|NullPointerException e) {
// Caught errors indicate a problem with data format -> Print warning and continue
System.out.println("Invalid line: "+ line);
}
}
return result;
} finally {
br.close();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,catch语句使用 Java 7 multi-catch。对于较旧的 Java 版本,请将其拆分为 3 个 catch 块或替换ArrayIndexOutOfBoundsException|NumberFormatException|NullPointerException为Exception. 后者通常是不鼓励的,因为它也掩盖并忽略了所有其他异常,但在像这样的简单示例中,风险可能不太高。
不幸的是,这个答案特定于您的问题,但鉴于它非常简单,它也应该很容易适应其他情况......
您可以做的另一件事是line在 while 循环内使用正则表达式进行匹配,而不是简单地根据逗号将其拆分。这样,您还可以一次性实现数据验证(例如,只匹配鞋号的合理数字)。
请注意,如果您的姓名包含逗号,然后用引号括起来(例如“Jackson, Jr.”作为姓氏),则上述实现将不起作用。如果您使用如上所述的正则表达式,或者通过检查姓氏的第一个字母并且如果它是引号,则可以“轻松”地涵盖这种情况,将 item[1] 与 item[2] 组合并使用 item[3] ] 和 item[4] 代替鞋码和性别。此处建议的大多数外部库可能会涵盖这种特殊情况,因此,如果您不担心任何依赖项、许可问题和性能问题,那么这些可能是更简单的出路...
Leo*_*Leo -1
我认为 SuperCSV + Dozer 易于使用,并且对于 java bean CSV 序列化非常强大
http://supercsv.sourceforge.net/dozer.html
| 归档时间: |
|
| 查看次数: |
4317 次 |
| 最近记录: |