Предварительное ожидание в файл мультигигабайта

Каков был бы самый производительный способ предварительно ожидать отдельный символ в файл мультигигабайта (в моем практическом случае, файле на 40 ГБ).

Нет никакого ограничения на реализацию, чтобы сделать это. Значение его может быть через инструмент, сценарий оболочки, программу в любом языке программирования...

10
задан dafmetal 22 April 2010 в 12:45
поделиться

7 ответов

По-настоящему простого решения не существует. Нет системных вызовов для добавления данных, только добавление или перезапись.

Но в зависимости от того, что вы делаете с файлом, вы можете обойтись без уловок. Если файл используется последовательно, вы можете создать именованный канал и поместить ] cat onecharfile.txt bigfile> namedpipe , а затем использовать «namedpipe» в качестве файла. То же самое можно сделать с помощью cat onecharfile.txt bigfile | запрограммируйте , если ваша программа принимает в качестве входных данных стандартный ввод.

Для произвольного доступа можно создать файловую систему FUSE, но, вероятно, она слишком сложна для этого.

Если вы хотите по-настоящему запачкать руки, выясните, как

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

Это может серьезно повредить вашу файловую систему, поэтому не рекомендуется; хорошо повеселиться.

8
ответ дан 3 December 2019 в 23:12
поделиться

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

Добавлено: Храните файл в двух подфайлах: A (короткий) и B (длинный). Приготовьте к A как хотите. Когда A станет «достаточно большим», добавьте A к B (переписав) и очистите A.

Другой способ: сохранить файл как каталог небольших файлов ..., A000003, A000002, A000001.
Просто добавьте файл с наибольшим номером. Когда он станет достаточно большим, сделайте следующий файл по порядку.
Если вам нужно прочитать файл, просто прочтите их все в порядке убывания.

4
ответ дан 3 December 2019 в 23:12
поделиться

, если вы имеете в виду добавить этот символ в начало всего файла, односторонне

$ echo "C" > tmp
$ cat my40gbfile >> tmp
$ mv tmp my40gbfile

или с помощью sed

$ sed -i '1i C' my40gbfile

, если вы имеете в виду добавление символа к каждой строке файла

$ awk '{print "C"$0}' my40gbfile > temp && mv temp my40gbfile
0
ответ дан 3 December 2019 в 23:12
поделиться

Насколько я понимаю, это обрабатывается на уровне файловой системы, то есть, если вы добавляете данные в файл, он эффективно перезаписывает файл. По этой же причине теги ID3 в файлах MP3 заполняются нулями, так что будущие обновления не перезаписывают весь файл, а просто обновляют эти зарезервированные байты.

Таким образом, какой бы способ вы ни использовали, вы получите примерно одинаковые результаты. Что вы можете попробовать, так это провести несколько тестов с настраиваемой функцией копирования, которая считывает / записывает более крупные фрагменты, чем системная копия по умолчанию, скажем, 2 МБ или 5 МБ, что может улучшить производительность. В конечном итоге узким местом здесь является дисковый ввод-вывод.

0
ответ дан 3 December 2019 в 23:12
поделиться

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

Я думаю, что это тот случай, когда C - очевидный выбор, такие низкоуровневые вещи - это именно то, чем является язык системного программирования для .

Не могли бы вы рассказать нам, чем вы в конечном итоге занимаетесь? Было бы интересно.

0
ответ дан 3 December 2019 в 23:12
поделиться

Вот способ командной строки Windows ("DOS"):

Поместите 1 символ в prepend.txt

copy /b prepend.txt + myHugeFile fileNameOfCombinedFile
-1
ответ дан 3 December 2019 в 23:12
поделиться

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

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

2
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: