0

Writing a method to read in values from a CSV file. I haven't had much experience with BufferedReader. 4 columns and 50 rows in the test file I'm using. Its supposed to read in and assign to 4 variables(String category, String name, int quantity, BigDecimal price) and with the intent to pass these to a constructor later once I get the reading figured out. I printed the values to see where I'm at, and they are not reading in as expected(see below). I'm looking to read in the two strings, then the integer and lastly the bigdecimal. Its currently chopping some characters and seemingly skipping others, and not printing the new line as expected.

Can anyone help me understand what's going on? Thanks.

Also, why are the -1 and null values printing at the bottom? Am I not correctly closing the file after the 50th row?

 public static void readFromFile(){
  BufferedReader fileReader = null;
  String csvFile = "/Users/Acer/Documents/CS1400/Assignments/InventoryApp/inventory.csv";
  int fileSize = 50; //input.nextInt;            

     try {
        fileReader = new BufferedReader(new FileReader(csvFile));
        for (int i = 0; i < fileSize; i++){
           String category = fileReader.readLine();                                    
           String name = fileReader.readLine();                 
           int quantity = fileReader.read();               
           BigDecimal price = new BigDecimal(fileReader.read());               
           System.out.println(category + " " + name + " " + quantity + " " + price);                                       
        }           
     }
     catch (IOException ioe) {
        System.out.println(ioe.getMessage());
     } finally {
        try {
        fileReader.close();
        }
        catch (IOException ioe) {
               System.out.println(ioe.getMessage());
        }
     } 
}   

Current Output:

Golf,Bag,7,49.99 Baseball,Baseball,4,12.99 72 111
ckey,Puck,8,11.99 Basketball,Basketball,2,15 70 111
otball,Football,7,13.95 Soccer,Ball,6,20.99 71 111
lf,Putter,2,65.5 Baseball,Catchers Mitt,9,49.99 72 111
ckey,Stick,2,27.99 Basketball,Shorts,4,20 70 111
otball,Shoulder Pads,8,34.99 Soccer,Goal,2,44.99 71 111
lf,Tees,4,2.99 Baseball,Cleats,8,50 72 111
ckey,Skates,3,69.99 Basketball,Hoop,5,99.99 70 111
otball,Cleats,2,67.99 Soccer,Shin Guards,4,35.95 71 111
lf,Balls,8,20 Baseball,Pants,5,34.98 72 111
ckey,Gear Bag,3,30 Basketball,Jersey,5,24.99 70 111
otball,Jersey,3,24.99 Soccer,Cleats,6,56.99 71 111
lf,Driver,8,99.99 Baseball,Bat Bag,9,40 72 111
ckey,Goal,9,30 Basketball,Socks,5,20 70 111
otball,Cup,9,12.95 Soccer,Socks,5,12 71 111
lf,3 Wood,2,80.99 Baseball,Socks,3,12.99 72 111
ckey,Neck Guard,2,1.99 Basketball,Catchers Mask,2,32.95 70 111
otball,Cup,7,12 Soccer,Cones,9,11.99 71 111
lf,Irons,3,99.99 Baseball,Sunglasses,6,50 72 111
ckey,Helmet,5,23 Basketball,Shoes,3,74.95 70 111
otball,Helmet,1,13.99 Soccer,Goalie Gloves,8,14.99 71 111
lf,Wedge,2,50 Baseball,Batting Helmet,5,27.99 72 111
ckey,Cup,8,20 Basketball,Sleeves,4,13 70 111
otball,Gloves,6,20.95 Soccer,Jersey,7,30.99 71 111
lf,Cart,5,66.99 Baseball,Bat,6,50.99 -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
null null -1 -1
Ali Seyedi
  • 1,758
  • 1
  • 19
  • 24
cobes
  • 9
  • 3
  • There are [plenty of existing libraries](http://stackoverflow.com/questions/200609/can-you-recommend-a-java-library-for-reading-and-possibly-writing-csv-files) that will parse CSV for you. Why not use one of those? – dnault Apr 12 '16 at 21:24
  • dnault - Honestly, I'm new enough to Java to have started using other libraries. I downloaded the .jar file. Is it automatically installed after double clicking? Do I need to import the class? – cobes Apr 12 '16 at 21:34
  • Yes, you need to import the class. You also need to add the JAR to the Class Path when compiling your code and at runtime. If you're interested in learning more, you could start by googling "add jar to class path". – dnault Apr 14 '16 at 20:09

3 Answers3

2

Let's say your your file format looks like this:

Name,Category,Qty,Price

I would urge you to use fileReader.readLine() and line.split like this:

// String csvFile = "/Users/Acer/Documents/CS1400/Assignments/InventoryApp/inventory.csv";
public static void readFromFile(String fname){
  BufferedReader fileReader = null;
  String line
  try {
     fileReader = new BufferedReader(new FileReader(csvFile));
     while ((line = fileReader .readLine()) != null) {
       String data[] = line.split(",");
       String name = data[0];
       String category = data[1];
       String quantity = data[2];
       String price = data[3];
       System.out.println(category + " " + name + " " + quantity + " " + price);                                       
     }
     fileReader.close();         
   }
   catch (IOException ioe) {
     System.out.println(ioe.getMessage());
   } 
}   

The main reason you're getting the "null" and "-1" is because the original "for" loop was meaningless: you were trying to read 50 items regardless of what was in the actual file.

I didn't see any reason to translate qty and price from "String" ... but you could easily use Integer.parseInt(String val) and BigInteger(String val) to do the conversion if you wanted.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
0

fileReader.readLine() reads a line which consists of all of the 4 attributes.

In each iteration read only one line using String str = fileReader.readLine() and then split that line using String[] splited = str.split(","); and call your constructor after that.

String str;
while ((str = fileReader.readLine()) != null) {       
   String[] splited = str.split(",");       
   String category = splited[0];
   String name = splited[1];
   int quantity = Integer.parseInt(splited[2]);
   BigDecimal price = new BigDecimal(Integer.parseInt(splited[3]));                                           
}   

Also it's a better idea to use a library like OpenCSV which makes your program much more robust.

Ali Seyedi
  • 1,758
  • 1
  • 19
  • 24
0

Each time you perform a fileReader.readLine(), you are trying to read a whole line and not only a slot. You should read your file as follows:

String line = null;
while ((line = fileReader.readLine()) != null) {
   String[] slots = line.split(SEPARATOR);
   String category = slots[0];
   String name = slots[1];
   int quantity = Integer.parseInt(slots[2]);
   BigDecimal price = new BigDecimal(slots[3]);
   System.out.println(category + " " + name + " " + quantity + " " + price);
}

Notice that there is no need to specify the number of lines. Also, you should replace SEPARATOR with whatever separator is used in your CSV.

Hatim Khouzaimi
  • 515
  • 4
  • 11