SuperCSV从多个文件中读取并解析为一个bean对象
SuperCSV reading from multiple files and parsing into one bean object
我目前正在尝试使用 beanReader 读取多个 CSV 文件,然后从每个文件中取出几列并将它们解析为一个 bean。
到目前为止,我似乎无法将来自不同文件的列解析为一个 bean 对象。这甚至可以用 ICsvBeanReader 实现吗?
是的,有可能 :) 从 Super CSV 2.2.0 you can read into an existing bean (see javadoc) 开始。
以下示例同时使用 3 readers(对 3 个不同的文件进行操作)- 第一个 reader 用于创建 bean,另外 2 个仅更新现有的 bean。此方法假定每个文件具有相同的行数(并且每个行号代表同一个人)。如果他们不这样做,但他们共享一些唯一标识符,则您必须先将第一个文件中的所有记录读入内存,然后从标识符上匹配的 second/third 进行更新。
我试图让它变得更聪明一些,所以你不必 hard-code 名称映射 - 它只是消除了它不知道的 headers (这样 Super CSV 就不会尝试映射您的 bean 中不存在的字段 - 请参阅网站上的 partial reading examples)。当然,这只有在你的文件有 headers 时才有效——否则你只需要在适当的地方用空值对映射数组进行硬编码。
人豆
public class Person {
private String firstName;
private String sex;
private String country;
// getters/setters
}
示例代码
public class Example {
private static final String FILE1 = "firstName,lastName\nJohn,Smith\nSally,Jones";
private static final String FILE2 = "age,sex\n21,male\n24,female";
private static final String FILE3 = "city,country\nBrisbane,Australia\nBerlin,Germany";
private static final List<String> DESIRED_HEADERS = Arrays.asList("firstName", "sex", "country");
@Test
public void testMultipleFiles() throws Exception {
try (
ICsvBeanReader reader1 = new CsvBeanReader(new StringReader(FILE1), CsvPreference.STANDARD_PREFERENCE);
ICsvBeanReader reader2 = new CsvBeanReader(new StringReader(FILE2), CsvPreference.STANDARD_PREFERENCE);
ICsvBeanReader reader3 = new CsvBeanReader(new StringReader(FILE3), CsvPreference.STANDARD_PREFERENCE);){
String[] mapping1 = getNameMappingFromHeader(reader1);
String[] mapping2 = getNameMappingFromHeader(reader2);
String[] mapping3 = getNameMappingFromHeader(reader3);
Person person;
while((person = reader1.read(Person.class, mapping1)) != null){
reader2.read(person, mapping2);
reader3.read(person, mapping3);
System.out.println(person);
}
}
}
private String[] getNameMappingFromHeader(ICsvBeanReader reader) throws IOException{
String[] header = reader.getHeader(true);
// only read in the desired fields (set unknown headers to null to ignore)
for (int i = 0; i < header.length; i++){
if (!DESIRED_HEADERS.contains(header[i])){
header[i] = null;
}
}
return header;
}
}
输出
Person [firstName=John, sex=male, country=Australia]
Person [firstName=Sally, sex=female, country=Germany]
我目前正在尝试使用 beanReader 读取多个 CSV 文件,然后从每个文件中取出几列并将它们解析为一个 bean。
到目前为止,我似乎无法将来自不同文件的列解析为一个 bean 对象。这甚至可以用 ICsvBeanReader 实现吗?
是的,有可能 :) 从 Super CSV 2.2.0 you can read into an existing bean (see javadoc) 开始。
以下示例同时使用 3 readers(对 3 个不同的文件进行操作)- 第一个 reader 用于创建 bean,另外 2 个仅更新现有的 bean。此方法假定每个文件具有相同的行数(并且每个行号代表同一个人)。如果他们不这样做,但他们共享一些唯一标识符,则您必须先将第一个文件中的所有记录读入内存,然后从标识符上匹配的 second/third 进行更新。
我试图让它变得更聪明一些,所以你不必 hard-code 名称映射 - 它只是消除了它不知道的 headers (这样 Super CSV 就不会尝试映射您的 bean 中不存在的字段 - 请参阅网站上的 partial reading examples)。当然,这只有在你的文件有 headers 时才有效——否则你只需要在适当的地方用空值对映射数组进行硬编码。
人豆
public class Person {
private String firstName;
private String sex;
private String country;
// getters/setters
}
示例代码
public class Example {
private static final String FILE1 = "firstName,lastName\nJohn,Smith\nSally,Jones";
private static final String FILE2 = "age,sex\n21,male\n24,female";
private static final String FILE3 = "city,country\nBrisbane,Australia\nBerlin,Germany";
private static final List<String> DESIRED_HEADERS = Arrays.asList("firstName", "sex", "country");
@Test
public void testMultipleFiles() throws Exception {
try (
ICsvBeanReader reader1 = new CsvBeanReader(new StringReader(FILE1), CsvPreference.STANDARD_PREFERENCE);
ICsvBeanReader reader2 = new CsvBeanReader(new StringReader(FILE2), CsvPreference.STANDARD_PREFERENCE);
ICsvBeanReader reader3 = new CsvBeanReader(new StringReader(FILE3), CsvPreference.STANDARD_PREFERENCE);){
String[] mapping1 = getNameMappingFromHeader(reader1);
String[] mapping2 = getNameMappingFromHeader(reader2);
String[] mapping3 = getNameMappingFromHeader(reader3);
Person person;
while((person = reader1.read(Person.class, mapping1)) != null){
reader2.read(person, mapping2);
reader3.read(person, mapping3);
System.out.println(person);
}
}
}
private String[] getNameMappingFromHeader(ICsvBeanReader reader) throws IOException{
String[] header = reader.getHeader(true);
// only read in the desired fields (set unknown headers to null to ignore)
for (int i = 0; i < header.length; i++){
if (!DESIRED_HEADERS.contains(header[i])){
header[i] = null;
}
}
return header;
}
}
输出
Person [firstName=John, sex=male, country=Australia]
Person [firstName=Sally, sex=female, country=Germany]