Java: чтение и запись файла CSV - PullRequest
5 голосов
/ 06 июня 2010

Я читаю 2 CSV-файла: store_inventory & new_acquisitions.
Я хочу иметь возможность сравнить store_inventory CSV-файл с new_acquisitions. 1) Если имена предметов совпадают, просто обновите количество в store_inventory. 2) Если в new_acquisitions есть новый элемент, который не существует в store_inventory, то добавьте его в store_inventory.

Вот что я уже сделал, но это не очень хорошо. Я добавил комментарии, где мне нужно добавить taks 1 & 2 .
Любой совет или код для выполнения вышеперечисленных задач будет замечательно! спасибо.

    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 018 *

Ответы [ 7 ]

5 голосов
/ 06 июня 2010

Предлагаем вам использовать один из существующих синтаксических анализаторов CSV, например Commons CSV или Super CSV , вместо изобретения колеса. Должно сделать вашу жизнь намного проще.

3 голосов
/ 23 ноября 2012

Ваша реализация допускает распространенную ошибку - разрыв строки через запятую с использованием line.split(","). Это не работает, потому что сами значения могут содержать запятые. Если это произойдет, значение должно быть заключено в кавычки, и вам нужно игнорировать запятые в кавычках. Метод split не может этого сделать - я часто вижу эту ошибку.

Вот источник реализации, которая делает это правильно: http://agiletribe.wordpress.com/2012/11/23/the-only-class-you-need-for-csv-files/

2 голосов
/ 10 мая 2015

С помощью библиотеки с открытым исходным кодом 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 голос
/ 22 декабря 2012

Поскольку Java не поддерживает собственный анализ CSV-файлов, мы вынуждены полагаться на сторонние библиотеки. Opencsv - одна из лучших библиотек, доступных для этой цели. Он имеет открытый исходный код и поставляется с лицензией Apache 2.0, что делает возможным коммерческое использование.

Здесь эта ссылка должна помочь вам и другим в ситуациях!

1 голос
/ 06 июня 2010

Операция, которую вы выполняете, потребует, чтобы для каждого предмета в ваших новых приобретениях вам нужно было искать каждый предмет в инвентаре на соответствие. Это не только неэффективно, но сканер, который вы настроили для файла инвентаря, необходимо будет сбрасывать после каждого элемента.

Я бы посоветовал вам добавить свои новые приобретения и свой инвентарь в коллекции, а затем выполнить итерацию по новым приобретениям и найти новый предмет в своей коллекции инвентаря. Если элемент существует, обновите элемент. Если это не так, добавьте его в коллекцию инвентаря. Для этого упражнения было бы неплохо написать простой класс, содержащий элемент инвентаря. Его можно использовать как для новых приобретений, так и для инвентаря. Для быстрого поиска я бы предложил вам использовать HashSet или HashMap для сбора инвентаря.

В конце процесса не забудьте сохранить изменения в вашем файле инвентаря.

0 голосов
/ 13 февраля 2017

Вы можете использовать Apache Commons CSV API. К вашему сведению: https://stackoverflow.com/a/42198895/6549532

Пример чтения / записи

0 голосов
/ 12 декабря 2016

Для записи в 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();
            }
        }
    }
...