如何使用Super CSV处理列数未知的CSV文件

问题描述:

对于需要处理CSV文件的项目,我不知道运行前的列。 CSV文件是完全有效的,我只需要一次又一次地在几个不同的文件上执行一个简单的任务。我确实需要分析列的值,这就是为什么我需要使用库来处理CSV文件。为了简单起见,假设我需要做一些简单的事情,比如将日期列附加到所有文件,而不管它们有多少列。我想用Super CSV做到这一点,因为我也使用库来完成其他任务。如何使用Super CSV处理列数未知的CSV文件

我所苦恼的是更多的概念问题。如果我事先不知道有多少列,我不知道如何处理这些文件。我不确定我应该如何定义映射任意CSV文件的POJO,或者如果我不知道文件中将包含多少列,我应该如何定义Cell处理器。我如何动态创建匹配列数的Cell处理器?我如何根据CSV文件的标题定义POJO?

考虑我有两个CSV文件的情况:products.csv和address.csv。让我们假设我想为这两个文件添加一个日期列和今天的日期,而不必编写两个不同的方法(例如addDateColumnToProduct()和addDateColumnToAddress()),它们可以做同样的事情。

product.csv:

name, description, price 
"Apple", "red apple from Italy","2.5€" 
"Orange", "orange from Spain","3€" 

address.csv:

firstname, lastname 
"John", "Doe" 
"Coole", "Piet" 

基础上CSV文件的头信息,我怎么可能定义映射的产品CSV一个POJO? Cell处理器的相同问题?我怎么能够定义一个非常简单的单元处理器,它基本上具有构造函数的正确参数量,例如对于product.csv

CellProcessor[] processor = new CellProcessor[] { 
    null, 
    null, 
    null 
}; 

,为address.csv:

CellProcessor[] processor = new CellProcessor[] { 
    null, 
    null 
}; 

这甚至可能吗?我在错误的轨道上实现这一目标吗?

编辑1:寻找能够处理具有在一个文件中的变量列的CSV文件的解决方案。我试图找出是否可以在运行时处理任意的CSV文件,也就是说,我可以仅基于包含在CSV文件中的标题信息在运行时创建POJO。事先不知道csv文件将有多少列。基于答案

解决方案 和@baba评论

private static void readWithCsvListReader() throws Exception { 

     ICsvListReader listReader = null; 
     try { 
       listReader = new CsvListReader(new FileReader(fileName), CsvPreference.TAB_PREFERENCE); 

       listReader.getHeader(true); // skip the header (can't be used with CsvListReader) 
       int amountOfColumns=listReader.length(); 
       CellProcessor[] processor = new CellProcessor[amountOfColumns]; 
       List<Object> customerList; 

       while((customerList = listReader.read(processor)) != null) { 
         System.out.println(String.format("lineNo=%s, rowNo=%s, customerList=%s", listReader.getLineNumber(), 
           listReader.getRowNumber(), customerList)); 
       } 

     } 
     finally { 
       if(listReader != null) { 
         listReader.close(); 
       } 
     } 
} 

也许有点晚,但可能会有所帮助......

CellProcessor[] processors=new CellProcessor[properties.size()]; 

    for(int i=0; i< properties.zise(); i++){ 
      processors[i]=new Optional(); 

    } 
    return processors; 
+0

'for(int i = 0; i Sid

这是一个很常见的问题,也有对internetz多个教程,包括超级的CSV页:

http://supercsv.sourceforge.net/examples_reading_variable_cols.html

正如此行所示:

如下所示,可以通过调用executeProcessors()方法调用 read()后执行单元处理器。因为在读取CSV行之后完成了 ,所以您有机会检查有多少列(使用listReader.length())并提供了正确数量的处理器。

+0

这似乎不是“变量列”实际上他们的意思_optional栏_。看起来您已经为每个可能的列数提供了一个处理器,以使其工作。 – Kapep

+0

您可以通过解析头文件预先观察cols的数量,然后对您使用的处理器数量做出明智的决定。 –

+0

感谢@baba,我编辑我的问题更加精确。我知道我可以解析头并计数列,但是如何在运行时创建一个具有动态数量参数的新CellProcessor对象(例如每列有一个“null”参数)? – Stefan