解析单个CSV行

时间:2013-10-28 03:19:20

标签: java csv

我有一个CSV文件的规范:

  • Key - Structured as Category:ID,其中ID是序列号。那里 不需要(或使用)将它分成两部分,只需要对待它 key作为单个唯一值
  • 品牌 - 产品制造商
  • 型号 - 产品的型号名称
  • WeightInKg - 产品重量,四舍五入到最接近的千克
  • 价格 - 将产品的售价提高到小数点后两位(2dp)

我已经有了这段代码来标记每一行:

public WarehouseItem(String warehouseItem) {
  String key, brand, model;
  int weightInKG;
  double price; 
  StringTokenizer strTok;

  strTok = new StringTokenizer(warehouseItem);
  try {
    key = strTok.nextToken();
    brand = strTok.nextToken();
    model = strTok.nextToken();
    weightInKG = Integer.parseInt(strTok.nextToken());
    price = Double.valueOf(strTok.nextToken());
  }
  catch (Exception e) {
    throw new IllegalStateException("CSV row had invalid format");
  }
}

当我尝试运行它时,我得到了CSV文件的IllegalStateException。

Exception in thread "main" java.lang.IllegalStateException: CSV row had invalid format
    at WarehouseItem.<init>(WarehouseItem.java:23) // throwing exception
    at main.loadRecords(main.java:63) // records[numRows] = new WarehouseItem(warehouseItem); storing into array of objects
    at main.main(main.java:26) // loadRecords(); calling the function which reads a line
    at main.loadRecords(main.java:78) // main(null); recursing back to main
    at main.main(main.java:26) // loadRecords(); calling the function which reads a line

下面是CSV文件中一行的示例:

长椅:6,Fremarc,豪华,101,1871.7

我想也许是因为钥匙有ID作为序列号?或者这根本不重要?我很困惑,任何帮助将不胜感激

2 个答案:

答案 0 :(得分:7)

你可能最喜欢图书馆。解析CSV可能会非常棘手。看看OpenCSV:

http://opencsv.sourceforge.net/

CSVParser parser = new CSVParser();
String[] fields = parser.parseLine(line);

答案 1 :(得分:3)

StringTokenizer对于您尝试做的事情来说有点沉重(同时,如果您希望使用双引号解析确切的CSV格式,则不够复杂)。

更简单的方法是使用String.split方法,如下所示:

public WarehouseItem(String warehouseItem) {
    String key, brand, model;
    int weightInKG;
    double price; 
    String[] tok = warehouseItem.split(",");
    if (tok.length != 5) {
        throw new IllegalStateException("Invalid CSV: not enough columns");
    }
    key = tok[0];
    brand = tok[1];
    model = tok[2];
    weightInKG = Integer.parseInt(tok[3]);
    price = Double.valueOf(tok[4]);
    // Do something with the values you've got
    ...
}