简体   繁体   中英

Reading CSV file in Java and storing the values in an int array

I have a CSV file of strings in this format:

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

All I want to do is read in the csv file and then store the 3rd and 4th coloumns data in integer arrays.

This is the code I have written:

    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();

I want to end up with two arrays, EMA which contains all the values from the 3rd coloumn and SMA which contains the values from the 4th coloumn.

I am getting a null pointer exception. Can someone please tell me what mistake I am making?

Your file appears to use whitespace/tab as a delimiter, but you're splitting at commas. That makes no sense to me.

You assume that the data row has a certain length without checking it. That makes no sense to me.

This code will show you how to do it better:

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;
    }
}

Here's the input file I used to test it:

# 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

Here's the output I got:

{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

[1] There should be a count++ inside the while loop

[2] You have not defined/initialized the arrays EMA and SMA - causing the exception.

[3] If you split() by comma and have a space separated file, the result will be an array of unity length, and indices 2 and 3 with generate NullPointerException - even if you initialize the arrays properly.

I suggest reading in the number by adding them to a List (like ArrayList or Vector) in the loop, since you do not know the size in advance. Once you get out of the loop, create 2 arrays of appropriate size and copyInto() the data in the arrays. Let the garbage collector deal with the Vectors.

The problem with your code is that int[] EMA is not an initialization. It just defines that EMA is an array of integers, without effectively creating it (you only have the reference).

My advice would be changing EMA and SMA to ArrayLists and instead of using attributions, you could add the current elements to the lists.

In the end of the loop, you get the number of elements at each ArrayList using the size() method and can change them into arrays using toArray method, fulfilling whichever goal you might have.

Of course, I am assuming that you forgot the commas at your example. Otherwise, you should change the delimiter to whitespace.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM