Эффективный по времени способ добавления к существующему заголовку в существующем CSV-файле в Java?

Я хотел бы изменить первую строку или заголовок существующего CSV-файла, добавив строку в конец этой строки.

Я пытался использовать BufferedWriter для этого, но я могу только добавить его в конец файла.

Мой рабочий код:

      public static void writeStringtoCsvFile(String filePath, String input) throws IOException {
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filePath, true)));
    out.append(input);
    out.close();
  }

Кажется, у OpenCsv нет доступного метода для добавления к существующему файлу. Файл, который мне нужно обработать, имеет размер не менее 160 МБ или 1+ mil записей, будет ли альтернативный метод:

  1. BufferedReader для чтения всех строк
  2. Добавьте все необходимое в первую строку
  3. BufferedWriter для записи всего в новый файл

быть слишком медленным? Есть ли более элегантное решение для этого? Спасибо!


person Mark    schedule 12.07.2020    source источник
comment
Учитывая, что вы не хотите добавлять в файл, а изменять его содержимое, нет никакого способа переписать его целиком.   -  person Voo    schedule 12.07.2020
comment
Если вы контролируете исходное создание файлов, то в некоторых случаях вы можете оптимизировать этот процесс. Если вы можете добавить несколько дополнительных байтов в первую строку, возможно, завершающие пробелы, при создании файла, то, когда его необходимо обновить, вы можете использовать RandomAccessFile и перезаписать некоторые дополнительные байты.   -  person tgdavies    schedule 12.07.2020


Ответы (1)


Файловые системы не позволяют вставлять байты или удалять байты из середины файла без перезаписи всех байтов после точки вставки/удаления.

Поскольку файловая система не поддерживает его, API-интерфейсы файлового ввода-вывода Java не могут его поддерживать.

Поскольку API-интерфейсы файлового ввода-вывода Java не поддерживают его, API-интерфейсы OpenCvs не поддерживают его. (Или, по крайней мере, без перезаписи файла под одеялом.)

Итак, ответ заключается в том, что нет более эффективного способа, чем чтение и запись всех строк файла.

Примечания:

  1. Хотя технически возможно перезаписать файл на месте, безопаснее (и, возможно, более эффективно) создать новый файл, записать в него и переименовать после завершения записи.

  2. Чтение и запись строки за раз (используя BufferedReader/BufferedWriter) лучше, чем одновременное чтение всех строк в память, а затем их запись. Особенно, если файлы большие.

person Stephen C    schedule 12.07.2020
comment
Не могли бы вы объяснить, как использовать BufferedWriter по сравнению с использованием библиотеки OpenCsv для записи в файл? Что будет быстрее? - person Mark; 12.07.2020
comment
Я думаю, что вы должны сделать это быстрее, используя BufferedWriter, так как вы можете избежать накладных расходов на синтаксический анализ и форматирование строк файла CSV. - person Stephen C; 12.07.2020
comment
Я попробовал метод, показанный выше, и на самом деле он, похоже, добавляется к той же последней строке файла, а не создает новую строку. Если бы я только мог заставить этот метод работать для ПЕРВОЙ строки, а не LOL ... и это вообще ожидается ?? - person Mark; 12.07.2020
comment
Да. Это ожидаемо. Рабочий код в вашем вопросе неверен. Вам нужно реализовать это так, как я предлагаю в своем ответе. Чтение строк из средства чтения и запись их в средство записи... со специальной обработкой первой строки (заголовка). - person Stephen C; 12.07.2020