Можно ли добавить данные в файл без перезаписи? - PullRequest
11 голосов
/ 30 января 2011

Я имею дело с очень большими двоичными файлами (от нескольких ГБ до нескольких ТБ на файл). Эти файлы существуют в устаревшем формате, и для обновления требуется записать заголовок в FRONT файла. Я могу создать новый файл и переписать данные, но иногда это может занять много времени. Мне интересно, есть ли более быстрый способ выполнить это обновление. Платформа ограничена Linux, и я готов использовать приемы низкоуровневых функций (ASM, C, C ++) / файловой системы, чтобы это произошло. Первичная библиотека - это Java, а JNI полностью приемлем.

Ответы [ 5 ]

9 голосов
/ 30 января 2011

Нет общего способа сделать это изначально.

Возможно, некоторые файловые системы предоставляют некоторые функции для этого (не может дать никакой подсказки об этом), но ваш код будет зависеть от файловой системы.


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

4 голосов
/ 30 января 2011

Звучит безумно, но вы можете хранить данные в обратном порядке, если есть возможность изменить функцию, которая читает данные из файла. В этом случае вы можете добавить данные (в обратном порядке) в конец файла. Это просто общая идея, поэтому я не могу рекомендовать что-то конкретное. Код для обращения к текущему файлу может выглядеть так:

 std::string records;
 ofstream out;
std::copy( records.rbegin(), records.rend(), std::ostream_iterator<string>(out));
2 голосов
/ 31 января 2011

Это зависит от того, что вы подразумеваете под "уловками файловой системы". Если вы готовы разбираться с форматом файловой системы на диске, и размер заголовка, который вы хотите добавить, кратен размеру блока файловой системы, тогда вы можете написать программа для непосредственного управления структурами файловой системы на диске (с отключенной файловой системой).

Это предприятие примерно так же волосато, как и звучит - вероятно, оно того стоило бы, если бы у вас были сотни таких гигантских файлов для обработки.

0 голосов
/ 15 августа 2017

Я знаю, что это старый вопрос, но я надеюсь, что это поможет кому-то в будущем. Подобно симуляции файловой системы, вы можете просто использовать именованный канал:

mkfifo /path/to/file_to_be_read
{ echo "HEADER"; cat /path/to/source_file; } > /path/to/file_to_be_read

Затем вы запускаете устаревшую программу для /path/to/file_to_be_read, и ввод будет:

HEADER
contents of /path/to/source_file
...

Это будет работать до тех пор, пока программа читает файл последовательно и не делает mmap() или rewind() мимо буфера.

0 голосов
/ 30 января 2011

Я бы просто использовал стандартные инструменты Linux для этого.
Написание другого приложения для этого кажется неоптимальным.

cat headerFile oldFile > tmpFile && mv tmpFile oldFile
...