Подтвердить что ты не робот

Как объединить 2 больших файла

Предположим, у меня есть 2 файла размером 100G каждый. И я хочу объединить их в один, а затем удалить их. В Linux мы можем использовать

cat file1 file2 > final_file

Но для этого нужно прочитать 2 больших файла, а затем написать файл большего размера. Можно ли просто добавить один файл к другому, чтобы не требовалось IO? Поскольку метаданные файла содержат местоположение файла и длину, мне интересно, можно ли изменить метаданные файла для слияния, поэтому не произойдет IO.

4b9b3361

Ответ 1

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

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

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

Можем ли мы сделать это лучше, чем удваивать размер обоих файлов?

Да, мы можем использовать операцию append (>>).

cat file2 >> file1

Это все равно приведет к использованию всего пространства, потребляемого file2 дважды, пока мы не сможем его удалить.

Можно ли использовать дополнительное пространство?

Нет. Если кто-то не вернется с чем-то, чего я не знаю, вам в основном не повезло. Возможно truncate файл, забывающий о существовании его конца, но нет способа забыть о существовании начало, если мы не вернемся к модификации inodes напрямую и должны изменить интерфейс ядра к файловой системе, поскольку это определенно не является операцией POSIX.

Как насчет написания немного за раз, а затем удаления того, что мы написали?

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

Как насчет разреженных файлов?

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

Объяснение всего этого - это другой ответ сам по себе, но если вы можете сделать свободное выделение, вы сможете использовать только свой размер чтения chunk + немного больше на диске для выполнения этой операции. Для справки о разреженных блоках в середине файлов см. http://lwn.net/Articles/357767/ или выполните поиск с участием термина SEEK_HOLE.

Почему это "возможно" вместо "да"? Две части: вам нужно будет написать свой собственный инструмент (по крайней мере, мы на правильном сайте для этого), а разреженные файлы не повсеместно соблюдаются файловыми системами и другими процессами. К счастью, вам, вероятно, не придется беспокоиться о других процессах, касающихся вашего файла, но вам придется беспокоиться о настройке правильных флагов и обеспечении соответствия вашей файловой системы. В конце концов, вы все равно будете читать и переписывать длину file2, чего вы не хотите. Этот метод означает, что вы можете добавить только небольшое количество дискового пространства, хотя, скорее, используя как минимум 2*file2 объем пространства.

Ответ 2

Вы можете сделать это следующим образом:

cat file2 >> file1

file1 станет полным контентом.

Ответ 3

Нет, невозможно объединить (в Linux) два больших файла, работая над их метаданными.

Возможно, вы могли бы рассмотреть какую-то базу данных для своей работы.

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