Можно ли средствами java, не загружая файл в память перезаписать строку?

Есть очень большой текстовый файл содержащий список. Количество строк — миллиард и больше. Если загружать его в память как массив байтов, типа Files.readAllBytes() и перебирать, может возникнуть ошибка OutOfMemoryError. Другие методы будут работать медленно.. Нашёл интересное решение для чтения с заданной строки.

Process p = Runtime.getRuntime().exec("tail -"+nLines+" "+file);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));

Можно ли таким же образом перезаписать или удалить строку в файле?


Ответы (1 шт):

Автор решения: Vadik

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

Возможно, ваша проблема может быть решена с помощью RandomAccessFile, но вы должны знать на какое количество байт вам нужно сместиться от начала файла, чтобы писать сразу в середину файла. Вы также не сможете удалять текст из середины, так как это бы означало, что вам нужно перезаписать оставшуюся половину файла. Но вы можете имитировать удаление заменой символов на пробелы.

Допустим, у вас есть файл input.txt в кодировке ASCII со следующим содержимым:

abcd
efgh
ijkl
mnop

Зная длину каждой строки, мы можем перезаписать третью строку на другое значение:

File file = new File("input.txt");
int lineLength = 4; // длина каждой строки
int lineNumber = 3; // номер строки для записи
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
    raf.seek((lineLength + 1) * (lineNumber - 1));
    raf.writeBytes("IJKL");
}

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

→ Ссылка