【问题标题】:csv parser reading headerscsv解析器读取标题
【发布时间】:2012-06-28 00:03:39
【问题描述】:

我正在开发一个 csv 解析器,我想分别读取标题和 csv 文件的其余部分。 这是我读取 csv 的代码。

当前代码读取 csv 文件中的所有内容,但我需要单独读取标题。 请帮我解决这个问题。

public class csv {

private void csvRead(File file)
{
    try
    {
    BufferedReader br = new BufferedReader( new FileReader(file));
    String strLine = "";
    StringTokenizer st = null;
    File cfile=new File("csv.txt");
    BufferedWriter writer = new BufferedWriter(new FileWriter(cfile));
    int tokenNumber = 0;

    while( (strLine = br.readLine()) != null)
    {
            st = new StringTokenizer(strLine, ",");
            while(st.hasMoreTokens())
            {

                    tokenNumber++;
                    writer.write(tokenNumber+"  "+ st.nextToken());
                    writer.newLine();
            }


            tokenNumber = 0;
            writer.flush();
    }
}

    catch(Exception e)
    {
        e.getMessage();
    }
}

【问题讨论】:

  • 如果你想将标题的读取与文件的其余部分分开,那么有一个只处理第一行的方法,另一个处理文件中所有其他行的方法。跨度>

标签: java parsing csv


【解决方案1】:

我们有 CSVFormat 中可用的 withHeader() 方法。如果您使用此选项,那么您将能够使用标题读取文件。

CSVFormat format = CSVFormat.newFormat(',').withHeader();
Map<String, Integer> headerMap = dataCSVParser.getHeaderMap(); 

会给你所有的标题。

public class CSVFileReaderEx {
    public static void main(String[] args){
        readFile();
    }

    public static void readFile(){
         List<Map<String, String>> csvInputList = new CopyOnWriteArrayList<>();
         List<Map<String, Integer>> headerList = new CopyOnWriteArrayList<>();

         String fileName = "C:/test.csv";
         CSVFormat format = CSVFormat.newFormat(',').withHeader();

          try (BufferedReader inputReader = new BufferedReader(new FileReader(new File(fileName)));
                  CSVParser dataCSVParser = new CSVParser(inputReader, format); ) {

             List<CSVRecord> csvRecords = dataCSVParser.getRecords();

             Map<String, Integer> headerMap = dataCSVParser.getHeaderMap();
              headerList.add(headerMap);
              headerList.forEach(System.out::println);

             for(CSVRecord record : csvRecords){
                 Map<String, String> inputMap = new LinkedHashMap<>();

                 for(Map.Entry<String, Integer> header : headerMap.entrySet()){
                     inputMap.put(header.getKey(), record.get(header.getValue()));
                 }

                 if (!inputMap.isEmpty()) {
                     csvInputList.add(inputMap);
                } 
             }

             csvInputList.forEach(System.out::println);

          } catch (Exception e) {
             System.out.println(e);
          }
    }
}

【讨论】:

  • 不错,真的很不错
【解决方案2】:

请考虑使用Commons CSV。该库是根据RFC 4180 - Common Format and MIME Type for Comma-Separated Values (CSV) Files 编写的。什么是兼容阅读这样的行:

"aa,a","b""bb","ccc"

而且使用也很简单,只有3个类,根据文档还有一个小示例:

解析以制表符作为分隔符的 csv 字符串,'"' 作为可选 值封装器,以及以 '#' 开头的 cmets:

 CSVFormat format = new CSVFormat('\t', '"', '#');
 Reader in = new StringReader("a\tb\nc\td");
 String[][] records = new CSVParser(in, format).getRecords();

此外,您还可以使用已作为常量使用的解析器:

  • DEFAULT - 由 RFC 4180 定义的标准逗号分隔格式。
  • EXCEL - Excel 文件格式(使用逗号作为值分隔符)。
  • MYSQL - SELECT INTO OUTFILE 和 LOAD DATA INFILE 操作使用的默认 MySQL 格式。 TDF - 制表分隔格式。

【讨论】:

    【解决方案3】:

    你考虑过OpenCSV吗?

    上一个问题在这里...

    CSV API for Java

    看起来你可以很容易地拆分标题...

    String fileName = "data.csv";
    CSVReader reader = new CSVReader(new FileReader(fileName ));
    
    
    // if the first line is the header
    String[] header = reader.readNext();
    
    // iterate over reader.readNext until it returns null
    String[] line = reader.readNext();
    

    【讨论】:

      【解决方案4】:

      你的代码在这里,正在

      while( (strLine = br.readLine()) != null)
          {
            //reads everything in your csv
          } 
      

      将打印您的所有 CSV 内容。

      例如,以下内容会获取您的标头:

      Reader in = ...;
       CSVFormat.EXCEL.withHeader("Col1", "Col2", "Col3").parse(in);
      

      正如建议的那样,使用 apache commons 库中预定义的 CSVFormat 会更轻松。链接在这里 (https://commons.apache.org/proper/commons-csv/user-guide.html)。 干杯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-06
        • 2019-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多