Объединение файлов в виртуальный файл в Linux
В системе Linux, есть ли способ объединить ряд файлов в один открытый файл для чтения и записи, не занимая при этом еще N байтов дискового пространства? Я надеялся на что-то вроде монтирования этих файлов через loopback/devmapper для достижения этой цели.
У меня есть проблема, когда есть разделенные двоичные файлы, которые могут стать довольно большими. Я не хочу удваивать свои требования к пространству с массивным дисковым вводом-выводом только для временного чтения / записи содержимого этих файлов с помощью cat
объединяя их все в один огромный файл.
Я нашел этот проект здесь, но, похоже, он имеет очень специфический вариант использования и также зависит от Perl
4 ответа
Вы можете сделать это, комбинируя петлевые устройства и устройство отображения, благодаря "все это файл". Но с одним ограничением: размер файла не может быть изменен (так как вы не можете увеличить количество блочных устройств, записывая их). Поэтому, если вы хотите добавить данные, вам нужно создать более крупное блочное устройство и перезаписать добавленные фиктивные данные.
# for testing, Create 4 files
echo foo | dd of=block0 cbs=512 conv=block
echo bar | dd of=block1 cbs=512 conv=block
echo bat | dd of=block2 cbs=512 conv=block
echo baz | dd of=block3 cbs=512 conv=block
# Create a loop device for each of the 4 files
losetup /dev/loop0 block0
losetup /dev/loop1 block1
losetup /dev/loop2 block2
losetup /dev/loop3 block3
# Create a device map named "test" using those loop devices
(
echo "0 1 linear /dev/loop0 0"
echo "1 1 linear /dev/loop1 0"
echo "2 1 linear /dev/loop2 0"
echo "3 1 linear /dev/loop3 0"
) | dmsetup create test
$EDITOR /dev/mapper/test # use overwrite mode only
Для расширения файла вы можете создать большой разреженный файл и использовать его как дополнительное устройство.
Это можно сделать с помощью именованного канала в Linux.
Предположим, у вас есть файлы с именем file0, file1, file2, file3, file4, file5
# create a name pipe
$ mkfifo mynewfile
# cat to named file
$ cat file{0..5} > mynewfile &
В С программно вы можете сделать
mkfifo(mynewfile , 0777);
system("cat file{0..5} > mynewfile");
Затем используйте затем используйте mynewfile, как если бы вы читали из обычного файла.
mynewfile - это файл FIFO
Ответ, предоставленный Хауке Лагингом, хорош, но следует отметить, что первое число в этих эхо-строках не просто автоматически увеличивается на единицу. В этом примере это так, но если длина вашего блока0, блока1 и т. д. превышает один блок, эти числа должны увеличиваться на размер предыдущей эхо-строки. Наглядный пример этого, предоставленный kernel.org, приведен ниже, предполагая, что $1 — это ваш /dev/loop0, а $2 — ваш /dev/loop1:
#!/bin/sh
# Join 2 devices together
1=/dev/loop0
2=/dev/loop1
size1=`blockdev --getsz $1`
size2=`blockdev --getsz $2`
echo "0 $size1 linear $1 0
$size1 $size2 linear $2 0" | dmsetup create joined
Источник: https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/linear.html .
Для чтения вы можете less
несколько файлов, а затем использовать :n
а также :p
варианты пройти через них.
Для записи без прямого доступа к файлам вы не сможете писать в них.
Вы можете vim
несколько файлов, и он будет проходить в том порядке, в котором они были названы (т.е. vim fileA fileB fileC
- файл B открывается после закрытия файла A, файл C открывается после закрытия файла B).