【问题标题】:Reading CSV file in Java and storing the values in an int array在 Java 中读取 CSV 文件并将值存储在 int 数组中
【发布时间】:2013-01-01 21:24:06
【问题描述】:

我有一个这种格式的字符串 CSV 文件:

14/10/2011  422     391.6592    394.52324   0.039215686
13/10/2011  408.43  391.7612    395.0686031 0.039215686
12/10/2011  402.19  391.834     395.3478736 0.039215686

我要做的就是读取 csv 文件,然后将第 3 列和第 4 列数据存储在整数数组中。

这是我写的代码:

    BufferedReader CSVFile = 
            new BufferedReader(new FileReader("appleData.csv"));

    String dataRow = CSVFile.readLine(); 
    int count = 0;

    while (dataRow != null){
        String[] dataArray = dataRow.split(",");

        EMA[count] = dataArray[2];
        SMA[count] = dataArray[3];

        dataRow = CSVFile.readLine(); // Read next line of data.
    }
    // Close the file once all data has been read.
    CSVFile.close();

我想得到两个数组,EMA 包含来自第 3 列的所有值,而 SMA 包含来自第 4 列的值。

我得到一个空指针异常。谁能告诉我我犯了什么错误?

【问题讨论】:

  • 你为什么不只显示堆栈跟踪? NPE 发生在哪里?
  • NPE 发生在 EMA[count] = dataArray[2];
  • 你在哪里初始化EMA?
  • EMA 是一个全局变量,初始化如下: int[] EMA;
  • 这只是一个声明。您必须使用正确的大小初始化数组(尽管这应该引发 IndexOutOfBounds 而不是 NPE)。请出示代码。

标签: java csv


【解决方案1】:

您的文件似乎使用空格/制表符作为分隔符,但您以逗号分隔。这对我来说毫无意义。

您假设数据行有一定的长度而不检查它。这对我来说毫无意义。

此代码将向您展示如何做得更好:

package cruft;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * CsvParser
 * @author Michael
 * @link http://stackoverflow.com/questions/14114358/reading-csv-file-in-java-and-storing-the-values-in-an-int-array/14114365#14114365
 * @since 1/1/13 4:26 PM
 */
public class CsvParser {
    public static void main(String[] args) {
        try {
            FileReader fr = new FileReader((args.length > 0) ? args[0] : "resources/test.csv");
            Map<String, List<String>> values = parseCsv(fr, "\\s+", true);
            System.out.println(values);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Map<String, List<String>> parseCsv(Reader reader, String separator, boolean hasHeader) throws IOException {
        Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
        List<String> columnNames = new LinkedList<String>();
        BufferedReader br = null;
        br = new BufferedReader(reader);
        String line;
        int numLines = 0;
        while ((line = br.readLine()) != null) {
            if (StringUtils.isNotBlank(line)) {
                if (!line.startsWith("#")) {
                    String[] tokens = line.split(separator);
                    if (tokens != null) {
                        for (int i = 0; i < tokens.length; ++i) {
                            if (numLines == 0) {
                                columnNames.add(hasHeader ? tokens[i] : ("row_"+i));
                            } else {
                                List<String> column = values.get(columnNames.get(i));
                                if (column == null) {
                                    column = new LinkedList<String>();
                                }
                                column.add(tokens[i]);
                                values.put(columnNames.get(i), column);
                            }
                        }
                    }
                    ++numLines;
                }
            }
        }
        return values;
    }
}

这是我用来测试它的输入文件:

# This shows that comments, headers and blank lines work fine, too.
date        value1  value2      value3      value4
14/10/2011  422     391.6592    394.52324   0.039215686

13/10/2011  408.43  391.7612    395.0686031 0.039215686



12/10/2011  402.19  391.834     395.3478736 0.039215686

这是我得到的输出:

{date=[14/10/2011, 13/10/2011, 12/10/2011], value1=[422, 408.43, 402.19], value2=[391.6592, 391.7612, 391.834], value3=[394.52324, 395.0686031, 395.3478736], value4=[0.039215686, 0.039215686, 0.039215686]}

Process finished with exit code 0

【讨论】:

  • 感谢您提供如此详细的答案,我现在将尝试对我的代码实施类似的解决方案:)
  • 或者就拿我给你的那个。
【解决方案2】:

[1]while循环里面应该有count++

[2] 您尚未定义/初始化数组 EMA 和 SMA - 导致异常。

[3] 如果您使用逗号 split() 并有一个空格分隔的文件,则结果将是一个长度为单位的数组,并且索引 2 和 3 会生成 NullPointerException - 即使您正确初始化了数组。

我建议通过将它们添加到循环中的列表(如 ArrayList 或 Vector)来读取数字,因为您事先不知道大小。退出循环后,创建 2 个适当大小的数组并 copyInto() 数组中的数据。让垃圾收集器处理 Vectors。

【讨论】:

    【解决方案3】:

    您的代码的问题在于 int[] EMA 不是初始化。它只是定义 EMA 是一个整数数组,而没有有效地创建它(您只有参考)。

    我的建议是将 EMA 和 SMA 更改为 ArrayLists,而不是使用属性,您可以将当前元素添加到列表中。

    在循环结束时,您可以使用 size() 方法获取每个 ArrayList 的元素数量,并可以使用 toArray 方法将它们更改为数组,从而实现您可能拥有的任何目标。

    当然,我假设您忘记了示例中的逗号。否则,您应该将分隔符更改为空格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2013-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多