【问题标题】:Read a CSV file and convert it to java objects n lines at a time读取 CSV 文件并一次将其转换为 java 对象 n 行
【发布时间】:2021-06-02 19:40:15
【问题描述】:

我正在尝试使用OpenCSV 读取一个CSV 文件并将其映射到java POJO。以下是我的示例 csv 类,Student.java 是我的 POJO 文件

StudentData.csv

name, rollno, department, result, cgpa
amar, 42, cse, pass, 8.6
rohini, 21, ece, fail, 3.2
aman, 23, cse, pass, 8.9
rahul, 45, ee, fail, 4.6
pratik, 65, cse, pass, 7.2
raunak, 23, me, pass, 9.1
suvam, 68, me, pass, 8.2

readFile() 函数


    public List<Student> readFile() 
    { 
  
        // Hashmap to map CSV data to  
        // Bean attributes. 
        Map<String, String> mapping = new 
                      HashMap<String, String>(); 
        mapping.put("name", "Name"); 
        mapping.put("rollno", "RollNo"); 
        mapping.put("department", "Department"); 
        mapping.put("result", "Result"); 
        mapping.put("cgpa", "Pointer"); 
  
        // HeaderColumnNameTranslateMappingStrategy 
        // for Student class 
        HeaderColumnNameTranslateMappingStrategy<Student> strategy = 
             new HeaderColumnNameTranslateMappingStrategy<Student>(); 
        strategy.setType(Student.class); 
        strategy.setColumnMapping(mapping); 
  
        // Create castobaen and csvreader object 
        CSVReader csvReader = null; 
        try { 
            csvReader = new CSVReader(new FileReader 
            ("D:\\EclipseWorkSpace\\CSVOperations\\StudentData.csv")); 
        } 
        catch (FileNotFoundException e) { 
  
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
        CsvToBean csvToBean = new CsvToBean(); 
  
        // call the parse method of CsvToBean 
        // pass strategy, csvReader to parse method 
        List<Student> list = csvToBean.parse(strategy, csvReader); 
  
        return list; // I want to read and return 10 at a time
    } 

调用方法


    public void foo(){
    
    List<Student> students;
    do{
       students = readFile(); // requirement: should return a  list of 10
       sysout(students);
    }while(!students.isEmpty)
    }

但我想一次读取 CSV 文件 n 行,并将其映射到对象列表。 (假设我的文件有 100 条记录,我想一次读取 10 行到一个列表中)

【问题讨论】:

  • 你只需创建一个循环遍历整个文件,并在里面有一个计数器,计数为 10,然后重置
  • @BenjaminM 我已经更新了我的问题。在第二次迭代中,如何跳过第一个n 行并从(n+1)th 行开始读取

标签: java spring csv java-8 opencsv


【解决方案1】:

你可以这样做:

String[] line; // this will contain all columns of a single line in the csv file
int counter = 0;
List<String[]> chunk = new ArrayList<>();
while ((line = csvReader.readNext()) != null) {
  counter++;
  
  // do something with the line, for example:
  chunk.add(line);

  if(counter == 10) {
    counter = 0; // reset counter

    // do something when counter reached 10, for example:
    System.out.println(chunk);
    chunk.clear();
  }
}

if(counter > 0) {
  // do something if counter could not be reset, for example:
  System.out.println(chunk); // remaining items
}

最后一个if(counter &gt; 0) 语句可能很有用,例如,如果您希望计数器计数为 10,但 csv 文件中有 15 行。所以你可以为剩下的行运行一些代码。

【讨论】:

    【解决方案2】:

    我以您的代码为起点提出了解决方案。

    我写了一个过滤器来检查要跳过的行数和要返回的行数。

    class LineNumberFilter implements CsvToBeanFilter {
    
    private final int skip;
    
    private final int lines;
    
    private int counter;
    
    public LineNumberFilter(int skip, int lines) {
        this.skip = skip;
        this.lines = lines;
        counter = 0;
    }
    
    public boolean allowLine(String[] line) {
        counter++;
        
        return counter >= skip && counter < (skip + lines);
    }
    

    要使用它,您必须传递以下参数以跳过 2 行并返回 2 行。

    return csvToBean.parse(strategy, csvReader, new LineNumberFilter(2,2));
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用 Univocity 的 csv 解析器来解析 java。它支持通过注解映射到 java POJO。 Here'sunivocity 与其他 csv 解析器的性能比较

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-10
        • 2020-07-06
        • 1970-01-01
        • 2014-09-16
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 1970-01-01
        相关资源
        最近更新 更多