【问题标题】:Parsing Data from CSV to Array in Java在 Java 中将数据从 CSV 解析为数组
【发布时间】:2011-09-25 12:32:14
【问题描述】:

我正在尝试将 CSV 文件导入到可以在 Java 程序中使用的数组中。 CSV 文件已成功导入,输出出现在终端上,但抛出错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 
at CompareCSV.main(CompareCSV.java:19)

最后。此外,当我尝试调用数组中的元素时,它也显示相同的错误。我的代码如下:

import java.io.*;
import java.util.*;

public class CompareCSV {

    public static void main(String[] args) {

        String fileName = "sampledata1.csv";
        try {
            BufferedReader br = new BufferedReader( new FileReader(fileName));
            String strLine = null;
            StringTokenizer st = null;
            int lineNumber = 0, tokenNumber = 0;

            while((fileName = br.readLine()) != null) {
                lineNumber++;
                String[] result = fileName.split(",");
                for (int x=0; x<result.length; x++) {
                    System.out.println(result[x]);
                }
            }
        }

        catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }   
}

【问题讨论】:

  • 为什么在 for 循环中使用硬编码常量,而不是结果大小?
  • 您可以使用现有的 Java CSV API 来满足您的需求:例如 sourceforge.net/projects/csv4jsourceforge.net/projects/javacsv
  • @Perception 是对的,你确定你读完一行后有 3 个值吗?
  • @Perception:我这样做是为了临时测试我是否会继续遇到异常,实际上应该有什么结果.length
  • @Benoit:谢谢,我会检查一下!

标签: java csv stringtokenizer


【解决方案1】:

使用正确的 CSV 解析器比自己破解一个有缺陷的解析器要好得多:http://opencsv.sourceforge.net/

CSV 不是人们可能会想到的简单格式(是的,一行可以包含不分隔两条数据的 ,)。

【讨论】:

  • 如何将 opencsv 包调用到 Java 程序中?我之前尝试过实施它,但似乎并没有以某种方式正确。编辑:刚刚找到 /examples 目录。
  • 一个人应该能够解析一个简单的 csv 文件而不使用一些“csv4j”库......
  • 互联网上的其他阅读表明拉取 CSV 库可能更容易。但是,是的,如果您知道如何轻松地将简单的 CSV 文件解析为可供 Java 程序的其余部分访问的数组,我将不胜感激!
  • @Andreas_D:但是为什么要浪费时间呢? CSV 解析不能由 String.split 完成,因为 , 如果不包含在 "'s 中,则只是一个分隔符
  • @Roger:没有什么比下载库并让它完成工作更容易的了。您的代码中的具体问题是,即使长度比这短,您也最多迭代 3 次,但您还远没有 CSV 解析器。
【解决方案2】:

这是上述问题的答案

 public class Readline {

/**
 * @param args
 */
public static void main(String[] args) {
    String fileName = "C:/Users/karthikrao/Desktop/cvsFile.csv";
    ArrayList<Integer> margins = new ArrayList<Integer>();
    BufferedReader br;
    String line, token;
    int i;
    try {
        br = new BufferedReader(new FileReader(fileName));
        try {
            while ((line = br.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line, ",\"");
                i = 0;
                while (st.hasMoreTokens()) {
                    token = st.nextToken();
                    if (margins.size() <= i) {
                        margins.add((Integer) token.length());
                    } else {
                        margins.set(
                                i,
                                Math.max(margins.get(i),
                                        (Integer) token.length()));
                    }
                    i++;
                }
            }

            br = new BufferedReader(new FileReader(fileName));
            while ((line = br.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line, ",\"");
                i = 0;
                while (st.hasMoreTokens()) {
                    token = st.nextToken();
                    System.out.print(token);
                    for (int j = 0; j < margins.get(i) - token.length(); j++) {
                        System.out.print(" ");
                    }
                    System.out.print("|");
                    i++;
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

}

}

【讨论】:

    【解决方案3】:

    当有这么多优秀的库时,我建议你不要重新发明轮子。尝试uniVocity-parsers 并使用以下代码片段作为参考:

    public static void main(String[] args) throws FileNotFoundException {
    
        /**
         * ---------------------------------------
         * Read CSV rows into 2-dimensional array
         * ---------------------------------------
         */
    
        // 1st, creates a CSV parser with the configs
        CsvParser parser = new CsvParser(new CsvParserSettings());
    
        // 2nd, parses all rows from the CSV file into a 2-dimensional array
        List<String[]> resolvedData = parser.parseAll(new FileReader("/examples/example.csv"));
    
        // 3rd, process the 2-dimensional array with business logic
        // ......
    }
    

    如您所见,完成将 csv 数据解析为数组的任务只需要 2 行代码。此外,该库还提供了解析 CSV 数据的完整功能列表,具有出色的性能。

    【讨论】:

      【解决方案4】:

      看起来像您的假设,文件中的一行 always 包含三列,但并非所有行都如此。将 for 循环语句替换为以下行以消除异常并查看它发生的原因:

      for (int x=0; x<result.length; x++)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-21
        • 2023-03-17
        • 2013-06-04
        • 1970-01-01
        • 2018-05-16
        • 2014-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多