在 Linux 系统上,有没有办法将一系列文件连接成一个公开的文件以供读写,同时又不实际占用另外 N 字节的磁盘空间?我希望通过 loopback/devmapper 安装这些文件来实现这一点。
我遇到一个问题,就是拆分的二进制文件可能会变得非常大。我不想通过大量磁盘 IO 将这些文件的内容临时读/写到cat
一个巨大的文件中,从而让我的空间需求翻倍。
我找到了这个项目这里,但它似乎有一个非常具体的用例,并且还依赖于 perl
答案1
您可以通过结合循环设备和设备映射器来实现这一点,这要归功于“一切都是文件”。但有一个限制:文件大小无法更改(因为您无法通过写入来增加块设备)。因此,如果您想附加数据,那么您必须创建一个更大的块设备并覆盖附加的虚拟数据。
# 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
为了扩展文件,您可以创建一个大的稀疏文件并将其用作附加设备。
答案2
这可以使用 Linux 中的命名管道来完成。
假设您有名为file0, file1, file2, file3, file4, file5
# create a name pipe
$ mkfifo mynewfile
# cat to named file
$ cat file{0..5} > mynewfile &
在 C 语言中你可以这样编程
mkfifo(mynewfile , 0777);
system("cat file{0..5} > mynewfile");
然后使用 mynewfile 就像我们从普通文件中读取一样。
mynewfile 是 FIFO 文件
答案3
Hauke Laging 提供的答案很好,但需要注意的是,这些 echo 行中的第一个数字不会自动增加 1。在这个例子中确实如此,但如果您的 block0、block1 等的长度大于一个块,则这些数字必须按前一个 echo 行的大小增加。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
答案4
对于阅读,您可以less
阅读多个文件,然后使用:n
和:p
选项来浏览它们。
对于写入,如果不直接访问文件,您将无法写入它们。
您vim
也可以同时处理多个文件,系统会按照调用它们的顺序进行操作(例如,vim fileA fileB fileC
在文件 A 关闭后打开文件 B,在文件 B 关闭后打开文件 C)。