10

I am trying to read the csv file, "read_ex.csv", into an array. I have searched endlessly on the web/stackoverflow to find a way to read the file into an array. The best i have been able to do is read it in a streaming fashion, but I cant store it in an array due the variable size of the file. I belive that ArrayList is a method to deal with variable size array, but I don't know how to work with it. Essentially I want to be able to access the String array "values" after the while loop finishes.

import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;

public class sortarray {
     public static void main (String []agrs){
         String fileName= "read_ex.csv";
         File file= new File(fileName);


         try{
             Scanner inputStream= new Scanner(file);
             while(inputStream.hasNext()){
             String data= inputStream.next();
             String[] values = data.split(",");
             System.out.println(values[1]);
             }
             inputStream.close();
          }catch (FileNotFoundException e) {
             e.printStackTrace();
     }
     //This prints out the working directory
     System.out.println("Present Project Directory : "+ System.getProperty("user.dir"));

    }           

}
m1ddleware
  • 78
  • 2
  • 16
mikeL
  • 1,094
  • 2
  • 12
  • 24

3 Answers3

24

Although using the Apache CSV library as mentioned by @Minjun.Y is perfectly fine, I try to provide a solution that is closer to your code and maybe easier for you to follow:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class CsvParser {

    public static void main(String[] args) {
        String fileName= "read_ex.csv";
        File file= new File(fileName);

        // this gives you a 2-dimensional array of strings
        List<List<String>> lines = new ArrayList<>();
        Scanner inputStream;

        try{
            inputStream = new Scanner(file);

            while(inputStream.hasNext()){
                String line= inputStream.next();
                String[] values = line.split(",");
                // this adds the currently parsed line to the 2-dimensional string array
                lines.add(Arrays.asList(values));
            }

            inputStream.close();
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // the following code lets you iterate through the 2-dimensional array
        int lineNo = 1;
        for(List<String> line: lines) {
            int columnNo = 1;
            for (String value: line) {
                System.out.println("Line " + lineNo + " Column " + columnNo + ": " + value);
                columnNo++;
            }
            lineNo++;
        }
    }

}

Let's go through it step-by-step:

  1. I added 3 more imports: ArrayList, Arrays and List - you will see very soon for what they are good. They are all taken from the java.util library, a standard library that is available with every JDK.

  2. Every class name in Java starts with a capital letter (by convention - it will build with a small letter as well, but you should get used to this convention) - I "fixed" this in your code.

  3. I added a 2-dimensional array List<List<String>> lines = new ArrayList<>(). This might look a little confusing at first, but what it means is that we create a variable lines that holds the results of our parsing. The List<String> syntax means, that we have a generic type List that has a type parameter String - in other words: a list of strings. The whole List<List<String>> means we have a list of lists of strings, a 2-dimensional string array.

  4. With the lines.add(Arrays.asList(values)) in your while loop, we can add the lines that you parsed to this 2-dimensional array. Arrays.asList(values) transforms the String[] array into a List as we need it to be compatible to our List<List<...>> type. This allows your lines to have variable length.

  5. The last lines I added simply print the content of 2-dimensional array and should give you a good example for how to access the values in this array. If you need further help for this construct, check the foreach loop documentation.

Given this as an input file (read_ex.csv):

value_1-1,value_1-2,value_1-3,value_1-4
value_2-1,value_2-2,value_2-3,value_2-4
value_3-1,value_3-2,value_3-3,value_3-4
value_4-1,value_4-2,value_4-3,value_4-4
value_5-1,value_5-2,value_5-3,value_5-4

The program will print the following output:

Line 1 Column 1: value_1-1
Line 1 Column 2: value_1-2
Line 1 Column 3: value_1-3
Line 1 Column 4: value_1-4
Line 2 Column 1: value_2-1
Line 2 Column 2: value_2-2
Line 2 Column 3: value_2-3
Line 2 Column 4: value_2-4
Line 3 Column 1: value_3-1
Line 3 Column 2: value_3-2
Line 3 Column 3: value_3-3
Line 3 Column 4: value_3-4
Line 4 Column 1: value_4-1
Line 4 Column 2: value_4-2
Line 4 Column 3: value_4-3
Line 4 Column 4: value_4-4
Line 5 Column 1: value_5-1
Line 5 Column 2: value_5-2
Line 5 Column 3: value_5-3
Line 5 Column 4: value_5-4

Hope this helps :)

Michael Lihs
  • 7,460
  • 17
  • 52
  • 85
  • @Micheal Lihs, Thanks for the detail. You anserwed my question as well as a few others! – mikeL Oct 16 '16 at 22:15
  • I was looking for some thing like this :) thanks for the answer – Chaitanya Pujari May 14 '17 at 15:20
  • If any of the csv values contains the comma character, will your code handle it? I believe that using Apache's Commons solution handles those cases of escaped wicked characters inside your csv files. – Mladen B. Oct 03 '17 at 14:27
  • I get a compile error "Type List does not take parameters". Also, the input file lines are broken up and do not load nicely. It seems random, and sometimes the lines are broken at a field. Actually happens seven times for each line. That is, each input line is broken up seven times. – Baruch Atta Jul 01 '18 at 23:47
8

I am new to java and wold be open to any method that reads a csv into a file that a beginner could understand.

Here is an existing solution for you from Apache Commons, the Apache Commons CSV project. See the Apache Commons CSV parser guide.

It is very easy to use out of the box.

Here is a basic worfklow:

  • Create a class that has the fields that "match" the columns of csv file.
  • Each row in your csv is an object of that class with properties corresponding to the fields in your csv. Use the library to get each field and store it in your object in a loop.
  • In your loop, you will store the object with the fields/properties read from the csv in the ArrayList
  • After the loop ends, your ArrayList will have elements that "matches" the rows in your csv file. You are free to access any of the rows/elements in the list.

If you are not familiar with how List and ArrayList works in Java, please refer to pretty much any Java tutorials online including the Oracle Tutorial.

Search Stackoverflow for hundreds of posts about using Commons CSV.

Community
  • 1
  • 1
Minjun Yu
  • 3,497
  • 4
  • 24
  • 39
  • thanks for the link. In the line "Iterable records = CSVFormat.EXCEL.parse(in);", I assume "CSVRecord" is the class, but what is "CSVFormat.EXCEL.parse(in)" referring to. – mikeL Oct 16 '16 at 20:35
  • 1
    @mikeL Rather than guess, read the documentation. The class doc for [`CSVFormat`](https://commons.apache.org/proper/commons-csv/archives/1.4/apidocs/index.html) explains that five different formats are supported by Commons CSV. The [`EXCEL`](https://commons.apache.org/proper/commons-csv/archives/1.4/apidocs/org/apache/commons/csv/CSVFormat.html#EXCEL) is a constant (pre-defined) object for the particular flavor of CSV generated by Microsoft Excel app. To quote: Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is locale dependent… – Basil Bourque Oct 16 '16 at 20:42
-1

To parse csv file into an array use this following code.

const csv = require('csv-parser');
    const fs = require('fs');
    
    var csvData = [];
    var apiNames = [];
    fs.createReadStream("APIsName.csv")
    .pipe(csv(['ID',"API"]))
      .on('data', function (csvrow) {
        csvData.push(csvrow);
      })
      .on('end', function () {
    
        for (i = 0; i < 5; i++) {
    
          console.log(csvData);
        }
        for(y=0;y<apiNames.length;y++){
          console.log(apiNames[y].names);
        }
      });