【问题标题】:Java: CSV file read & writeJava:CSV文件读写
【发布时间】:2010-06-06 01:53:53
【问题描述】:

我正在阅读 2 个 csv 文件:store_inventory & new_acquisitions
我希望能够将store_inventory csv 文件与new_acquisitions 进行比较。 1) 如果项目名称匹配,只需更新 store_inventory 中的数量。 2) 如果new_acquisitions 有一个新的项目在store_inventory 中不存在,则将其添加到store_inventory

这是我到目前为止所做的,但不是很好。我在需要添加任务 12 的地方添加了 cmets。
任何完成上述任务的建议或代码都会很棒!谢谢。

    File new_acq = new File("/src/test/new_acquisitions.csv");
    Scanner acq_scan = null;
    try {
        acq_scan = new Scanner(new_acq);
    } catch (FileNotFoundException ex) {
        Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
    }
    String itemName;
    int quantity;
    Double cost;
    Double price;

    File store_inv = new File("/src/test/store_inventory.csv");
    Scanner invscan = null;
    try {
        invscan = new Scanner(store_inv);
    } catch (FileNotFoundException ex) {
        Logger.getLogger(mainpage.class.getName()).log(Level.SEVERE, null, ex);
    }
    String itemNameInv;
    int quantityInv;
    Double costInv;
    Double priceInv;


    while (acq_scan.hasNext()) {
        String line = acq_scan.nextLine();
        if (line.charAt(0) == '#') {
            continue;
        }
        String[] split = line.split(",");

        itemName = split[0];
        quantity = Integer.parseInt(split[1]);
        cost = Double.parseDouble(split[2]);
        price = Double.parseDouble(split[3]);


        while(invscan.hasNext()) {
            String line2 = invscan.nextLine();
            if (line2.charAt(0) == '#') {
                continue;
            }
            String[] split2 = line2.split(",");

            itemNameInv = split2[0];
            quantityInv = Integer.parseInt(split2[1]);
            costInv = Double.parseDouble(split2[2]);
            priceInv = Double.parseDouble(split2[3]);


            if(itemName == itemNameInv) {
                //update quantity

            }
        }
        //add new entry into csv file

     }

再次感谢您的帮助。 =]

【问题讨论】:

  • 如果你真正提出问题,你会发现你会得到更多更好的答案。

标签: java file csv java.util.scanner


【解决方案1】:

建议您使用现有的 CSV 解析器之一,例如 Commons CSVSuper CSV,而不是重新发明轮子。应该会让你的生活更轻松。

【讨论】:

【解决方案2】:

您的实现犯了一个常见错误,即使用line.split(",") 打破逗号。这不起作用,因为值本身可能包含逗号。如果发生这种情况,则必须引用该值,并且您需要忽略引号中的逗号。 split 方法不能做到这一点——我经常看到这个错误。

这是正确执行的实现的来源: http://agiletribe.purplehillsbooks.com/2012/11/23/the-only-class-you-need-for-csv-files/

【讨论】:

    【解决方案3】:

    借助开源库uniVocity-parsers,您可以使用以下非常简洁的代码进行开发:

    private void processInventory() throws IOException {
        /**
         * ---------------------------------------------
         *  Read CSV rows into list of beans you defined
         * ---------------------------------------------
         */
        // 1st, config the CSV reader with row processor attaching the bean definition
        CsvParserSettings settings = new CsvParserSettings();
        settings.getFormat().setLineSeparator("\n");
        BeanListProcessor<Inventory> rowProcessor = new BeanListProcessor<Inventory>(Inventory.class);
        settings.setRowProcessor(rowProcessor);
        settings.setHeaderExtractionEnabled(true);
    
        // 2nd, parse all rows from the CSV file into the list of beans you defined
        CsvParser parser = new CsvParser(settings);
        parser.parse(new FileReader("/src/test/store_inventory.csv"));
        List<Inventory> storeInvList = rowProcessor.getBeans();
        Iterator<Inventory> storeInvIterator = storeInvList.iterator();
    
        parser.parse(new FileReader("/src/test/new_acquisitions.csv"));
        List<Inventory> newAcqList = rowProcessor.getBeans();
        Iterator<Inventory> newAcqIterator = newAcqList.iterator();
    
        // 3rd, process the beans with business logic
        while (newAcqIterator.hasNext()) {
    
            Inventory newAcq = newAcqIterator.next();
            boolean isItemIncluded = false;
            while (storeInvIterator.hasNext()) {
                Inventory storeInv = storeInvIterator.next();
    
                // 1) If the item names match just update the quantity in store_inventory
                if (storeInv.getItemName().equalsIgnoreCase(newAcq.getItemName())) {
                    storeInv.setQuantity(newAcq.getQuantity());
                    isItemIncluded = true;
                }
            }
    
            // 2) If new_acquisitions has a new item that does not exist in store_inventory,
            // then add it to the store_inventory.
            if (!isItemIncluded) {
                storeInvList.add(newAcq);
            }
        }
    }
    

    只需按照我根据您的要求编写的代码示例即可。请注意,该库为解析 CSV 文件提供了简化的 API 和显着的性能。

    【讨论】:

      【解决方案4】:

      您正在执行的操作将要求对于新购置的每件商品,您都需要搜索库存中的每件商品以进行匹配。这不仅效率不高,而且您为库存文件设置的扫描仪需要在每件物品后重置。

      我建议您将新收购和库存添加到收藏中,然后遍历新收购并在库存收藏中查找新项目。如果该项目存在,则更新该项目。如果没有,请将其添加到库存集合中。对于这个活动,最好编写一个简单的类来包含库存项目。它可以用于新的收购和库存。为了快速查找,我建议您使用 HashSet 或 HashMap 来收集库存。

      在过程结束时,不要忘记将更改保存到您的库存文件。

      【讨论】:

        【解决方案5】:

        由于 Java 本身不支持解析 CSV 文件,我们必须依赖第三方库。 Opencsv 是可用于此目的的最佳库之一。它是开源的,附带 Apache 2.0 许可证,可用于商业用途。

        在这里,this link 应该可以帮助您和其他人!

        【讨论】:

          【解决方案6】:

          用于写入 CSV

          public void writeCSV() {
          
                  // Delimiter used in CSV file
                  private static final String NEW_LINE_SEPARATOR = "\n";
          
                  // CSV file header
                  private static final Object[] FILE_HEADER = { "Empoyee Name","Empoyee Code", "In Time", "Out Time", "Duration", "Is Working Day" };
          
                  String fileName = "fileName.csv");
                  List<Objects> objects = new ArrayList<Objects>();
                  FileWriter fileWriter = null;
                  CSVPrinter csvFilePrinter = null;
          
                  // Create the CSVFormat object with "\n" as a record delimiter
                  CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
          
                  try {
                      fileWriter = new FileWriter(fileName);
          
                      csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
          
                      csvFilePrinter.printRecord(FILE_HEADER);
          
                      // Write a new student object list to the CSV file
                      for (Object object : objects) {
                          List<String> record = new ArrayList<String>();
          
                          record.add(object.getValue1().toString());
                          record.add(object.getValue2().toString());
                          record.add(object.getValue3().toString());
          
                          csvFilePrinter.printRecord(record);
                      }
          
                  } catch (Exception e) {
                      e.printStackTrace();
                  } finally {
                      try {
                          fileWriter.flush();
                          fileWriter.close();
                          csvFilePrinter.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          

          【讨论】:

            【解决方案7】:

            您可以使用 Apache Commons CSV api。 仅供参考:https://stackoverflow.com/a/42198895/6549532

            Read / Write Example

            【讨论】:

              猜你喜欢
              • 2012-12-23
              • 1970-01-01
              • 2013-05-12
              • 2013-05-21
              • 2021-01-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多