在 Linux 上将文件连接到虚拟文件

在 Linux 上将文件连接到虚拟文件

在 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)。

相关内容