Java:CSV文件读写

5
我正在阅读两个csv文件:store_inventorynew_acquisitions。 我想要能够比较store_inventory csv文件和new_acquisitions。 1)如果商品名称匹配,只需更新store_inventory中的数量。 2)如果new_acquisitions有一个不存在于store_inventory中的新商品,则将其添加到store_inventory中。
以下是我迄今为止所做的,但不是很好。我在需要添加任务12的地方添加了注释。 任何关于完成上述任务的建议或代码都将非常感谢!谢谢。
    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

     }

再次感谢您的帮助。=]

1
如果你真正提出一个问题,你会发现你会得到更多更好的答案。 - Mark Peters
7个回答

5
建议您使用现有的CSV解析器(例如Commons CSVSuper CSV),而不是重新发明轮子。这样会使您的生活变得更加容易。

我下载了opencsv,但是我不知道如何使用这个库。你能指点我一下吗?我正在使用NetBeans。 - nubme
有关使用opencsv进行读写的示例,请参见http://opencsv.sourceforge.net/#how-to-read - seangrieve

3
您的实现存在常见错误,通过使用 line.split(",") 在逗号处断行。这样做是不起作用的,因为值本身可能有逗号。如果发生这种情况,必须将该值用引号括起来,并忽略引号内的逗号。split 方法无法做到这一点 - 我经常看到这个错误。
以下是正确执行此操作的实现源代码: http://agiletribe.purplehillsbooks.com/2012/11/23/the-only-class-you-need-for-csv-files/

2
借助开源库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);
        }
    }
}

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

1

您正在执行的操作需要为新采购的每个项目在库存中搜索匹配项。这不仅效率低下,而且您设置的库存文件扫描器需要在每个项目之后重新设置。

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

在流程结束时,请不要忘记将更改持久化到您的库存文件中。


1

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

在这里,此链接应该能够帮助您和其他人解决问题!


0

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接