BufferedReader在从CSV读取并分配到不同类型时跳过字段

时间:2016-04-12 21:18:50

标签: java bufferedreader

编写方法以从CSV文件读取值。我对BufferedReader没有多少经验。我正在使用的测试文件中有4列和50行。它应该读入并分配给4个变量(字符串类别,字符串名称,int数量,BigDecimal价格),并且意图在我读完读数后将这些传递给构造函数。我打印了值,看看我在哪里,他们没有按预期阅读(见下文)。我想读两个字符串,然后是整数,最后是bigdecimal。它目前正在砍掉一些角色,似乎正在跳过其他角色,而不是按预期打印新线。

任何人都可以帮我理解发生了什么吗?感谢。

另外,为什么-1和null值在底部打印?我在第50行之后没有正确关闭文件吗?

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

当前输出:

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

3 个答案:

答案 0 :(得分:2)

假设您的文件格式如下:

Name,Category,Qty,Price

我建议你像这样使用fileReader.readLine()line.split

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

你得到“null”和“-1”的主要原因是因为原来的“for”循环没有意义:你试图读取50个项目而不管实际文件中是什么。

我没有看到任何理由从“字符串”翻译数量和价格......但如果您愿意,可以轻松使用Integer.parseInt(String val)BigInteger(String val)进行转换。

答案 1 :(得分:0)

fileReader.readLine()读取一条由4个属性组成的行。

在每次迭代中只读取一行 String str = fileReader.readLine()然后使用String[] splited = str.split(",");拆分该行,并在此之后调用您的构造函数。

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

同样最好使用像OpenCSV这样的库,这样可以使您的程序更加健壮。

答案 2 :(得分:0)

每次执行fileReader.readLine()时,您都试图读取整行,而不仅仅是一个插槽。您应该按如下方式阅读您的文件:

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

请注意,无需指定行数。此外,您应该使用CSV中使用的任何分隔符替换SEPARATOR