我们可以将文件孔分配给另一个文件吗?

我们可以将文件孔分配给另一个文件吗?

参考 Unix 环境中的高级编程,当我们尝试查找文件末尾并在那里写入内容时,就会创建文件漏洞。例如,

    int x = lseek(fd,1639,SEEK_END);
    int y = write(fd,buff,100);

如果考虑上面的示例并假设该文件以前有一些内容,则当前文件偏移量位于文件开头之前的某个位置。现在,我们使用该函数查找文件末尾lseek(如上例所示),并写入一个缓冲区浅黄色文件大小为 100。如您所知,文件中将创建一个洞。

那么,Unix 可以将此漏洞分配给其他文件吗?或者,换句话说,这个洞是否可以分配?

答案1

首先,什么是文件中的漏洞?它只是将数据设置为零,而没有明确地这样写。当您seek超出文件末尾 1639 个字节并向其中写入 100 个字节时,您的文件实际上增长了 1639+100 个字节。因此,您创建了一个洞,但该洞实际上是用零填充的。

如果该漏洞足够大,某些文件系统(例如ext)允许您通过不在磁盘上分配相应的块来节省该空间。即,如果您seek要写入一个或多个零块,则这些块不会在磁盘上分配,这将在包含文件数据的块列表中创建真正的漏洞。这就是我们所说的稀疏文件

块的大小取决于 FS 的格式化方式。现在ext通常是 4096 字节。这意味着,通过 1639 字节查找,您不会创建稀疏文件,并且 1639 个零只会写入磁盘上。 OTOH,对于 4096 字节块,如果您寻求至少 8191 (2 * 4096 - 1) 字节,则可以确定至少创建一个。

由于块实际上并未分配并用零填充,这使得您的文件使用更少的磁盘空间,并且您的写入操作速度更快。当然,为了回答您的问题,空闲的磁盘空间可用于其他文件。

实际上,最好的演示并不需要 C 程序:

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

$ time dd of=/tmp/foo bs=1M seek=$((1024*1024*10)) count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 4.741e-05 s, 0.0 kB/s

real    0m0.002s
user    0m0.000s
sys 0m0.000s

$ ls -lh /tmp/foo
-rw-r--r-- 1 xhienne xhienne 10T Aug 25 20:08 /tmp/foo

$ df -h /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda4        38G   28G  7.5G  80% /

在这里,我在几毫秒内在一个只有 7+ GB 可用空间(仍然可用)的分区上创建了一个 10 TB 文件(全是零)。

相关内容