Добавление огромных файлов друг к другу без их копирования

Существует 5 огромных файлов (file1, file2, .. file5) около 10G каждый и крайне мало свободного места на диске, и мне нужно объединить все эти файлы в один. Нет необходимости хранить оригинальные файлы, только окончательные.

Обычная конкатенация идет с cat в последовательности для файлов file2 .. file5 :

 cat file2 >> file1 ; rm file2 

К сожалению, для этого пути требуется не менее 10 Гб свободного места, которого у меня нет. Есть ли способ конкатенации файлов без фактического копирования, но как-то сказать файловой системе, что файл1 не заканчивается в исходном конце file1 и продолжается при запуске file2?

пс. файловая система ext4, если это имеет значение.

4 Solutions collect form web for “Добавление огромных файлов друг к другу без их копирования”

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

Предположим сначала, что оба файла имеют точно 5GiB (5120 MiB) и что вы хотите переместить 100 MiB за раз. Вы выполняете цикл, который состоит из

  1. копирование одного блока с конца исходного файла в конец целевого файла (увеличение потребляемого дискового пространства)
  2. усечение исходного файла одним блоком (освобождение дискового пространства)

     for((i=5119;i>=0;i--)); do dd if=sourcefile of=targetfile bs=1M skip="$i" seek="$i" count=1 dd if=/dev/zero of=sourcefile bs=1M count=0 seek="$i" done 

Но сначала попробуйте с меньшими тестовыми файлами, пожалуйста …

Вероятно, файлы не имеют одинакового размера и не имеют кратного размера блока. В этом случае расчет смещений становится более сложным. seek_bytes и skip_bytes .

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

Предупреждение

В зависимости dd размера блока dd результирующий файл будет фрагментарным кошмаром.

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

 mkfifo /tmp/file cat file* >/tmp/file & blahblah /tmp/file rm /tmp/file 

Как предполагает Хауке, losetup / dmsetup также может работать. Быстрый эксперимент; Я создал файл 'file1..file4' и с небольшим усилием сделал:

 for i in file*;do losetup -f ~/$i;done numchunks=3 for i in `seq 0 $numchunks`; do sizeinsectors=$((`ls -l file$i | awk '{print $5}'`/512)) startsector=$(($i*$sizeinsectors)) echo "$startsector $sizeinsectors linear /dev/loop$i 0" done | dmsetup create joined 

Затем / dev / dm-0 содержит виртуальное блочное устройство с вашим файлом в качестве содержимого.

Я не проверил это хорошо.

Другое редактирование: размер файла должен быть делимым равномерно на 512 или вы потеряете некоторые данные. Если это так, тогда ты хороший. Я вижу, он также отметил это ниже.

Вам нужно будет написать что-то, что копирует данные в пучки, которые не превышают столько свободного места, которое у вас есть. Он должен работать следующим образом:

  • Прочтите блок данных из pread() (используя pread() , ища перед чтением в pread() место).
  • Добавьте блок в file1 .
  • Используйте fcntl(F_FREESP) чтобы освободить место из file2 .
  • Повторение

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

 #step 1 mount /path/to/... /the/new/fs #mount a new filesystem (from NFS? or an external usb disk?) 

а потом

 #step 2: cat file* > /the/new/fs/fullfile 

или, если вы считаете, что сжатие поможет:

 #step 2 (alternate): cat file* | gzip -c - > /the/new/fs/fullfile.gz 

Затем (и ТОЛЬКО тогда), наконец

 #step 3: rm file* mv /the/new/fs/fullfile . #of fullfile.gz if you compressed it 
  • Удалить пробелы в именах файлов в каталоге
  • Эффективно копировать имена в оболочке
  • Удалить все файлы с исполняемым разрешением в каталоге
  • Список X случайных файлов из каталога
  • Оптимальная стратегия управления файлами для одной библиотеки, распространяемой на три компьютера
  • Способы организации и доступа к часто посещаемым каталогам и файлам?
  • Переименование файлов в соответствии с количеством символов из имени каталога
  • Ограничение размера файла в соответствии с учебником Роберта Лава
  • Команда macOS rm '-W' - восстановить
  • Сводка использования диска для пользователя
  • Получить усеченный файл в NTFS
  • Interesting Posts

    Как заставить SSH `ControlPath` различать IPv4 и IPv6?

    Время ожидания SSH. это не клиент или сервер … что теперь?

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

    Помощь с функцией AWK

    Нужно ли шифровать файл swap *, если он будет находиться в зашифрованном корневом файле?

    Как я могу заставить node.js автоматически загружать файлы конфигурации?

    Запуск gui из события acpi

    проверьте, если сценарий оболочки принимает аргумент командной строки перед запуском

    Debian 9 apt-get update возвращает файловую систему ошибок только чтение

    Как вращать старые файлы журналов в уникальном файле .tar.gz?

    используя SSH для подключения к удаленному серверу CentOS 5.6, где Firefox работает на сервере очень медленно

    Не удалось удалить пакет openmediavault из-за ошибки сценария postrm

    Почему запись в / dev / random не делает параллельное чтение из / dev / random быстрее?

    / dev / sda1 смонтирован; не будет создавать файловую систему здесь!

    Средство просмотра изображений для нескольких изображений

    Linux и Unix - лучшая ОС в мире.