为什么没有文件插入系统调用


11

据我了解,在Linux中,只有用于操纵文件的sys_write syscall才会覆盖文件内容(或扩展到文件末尾)。

为什么在Linux中没有用于在文件中插入或删除内容的系统调用?

由于当前所有文件系统都不需要将文件存储在连续的内存块中,因此应该有可能实现高效的实现。(文件将变得碎片化。)

由于文件系统具有“写时复制”或“透明文件压缩”功能,因此当前插入内容的方式似乎效率很低。


4
与所有花式文件操作一样,这种操作在实践中远没有看上去有用。这种东西的主要用途是非常专业的应用程序,例如数据库,仿真器等。通常,“编辑”文件的方式是创建一个新文件,并由用户执行“保存”操作,将新文件重命名为旧文件。
mosvy

3
@mosvy,但是是否使用了“创建新文件,然后重命名”的概念,因为它本身很好,或者恰恰是因为系统没有提供更好的方法?尤其是在文本文件操作中,诸如“修改此行(更改长度)”或“在此处插入这些行”之类的操作相当普遍,因此可以假设,如果存在那些确切功能的文件系统操作将被使用。当然,没有它们会使fs的实现更加简单...
ilkkachu

1
@meuh OpenVMS仍然通过RMS(记录管理服务)进行操作。
罗恩·约翰

1
UNIX开始远离在文件系统内部提供记录管理系统的过程。
user207421 '19

1
@ilkkachu本身就很好,这是绝对好的;-)而且,如果inode是不可变的,这将使实现块共享,版本控制以及几乎所有事情都更加高效(并且推理起来也更加简单)。打个比方,想一想所有脚本语言如何都转换为不可变的字符串-但在这里我将简短介绍;很难谈论文件系统,而且听起来不像是庸医的;-)
mosvy

Answers:


22

在最新的Linux系统上,实际上是可行的,但是使用(大多数情况下为4096),而不是字节粒度,并且仅在某些文件系统(ext4和xfs)上。

从手册fallocate(2)页引用:

int fallocate(int fd, int mode, off_t offset, off_t len);

[...]

折叠的文件空间

在中指定FALLOC_FL_COLLAPSE_RANGE标志(从Linux 3.15开始可用)mode从文件中删除字节范围,而不会留下漏洞。要折叠的字节范围始于offset并继续为 len 字节。操作完成后,将从该位置开始的文件内容offset+len添加到location处 offset,并且文件将len变小字节。

[...]

增加文件空间

在不指定任何现有数据的情况下,通过在文件大小中插入一个孔来指定FALLOC_FL_INSERT_RANGE标志(从Linux 4.1开始可用)来mode增加文件空间。孔将从处开始 offset并继续len字节。在文件中插入孔时,从处开始的文件内容offset将向上移动(即,移至更高的文件偏移量)len字节。在文件内插入孔会增加文件大小(以len字节为单位)。


1
“但是使用块(4096),而不是字节粒度” -4KiB块在ext4中非常常见,但这不能保证。Ext4 支持1KiB,2KiB和4KiB块大小;我记得从ext2开始,在Alpha处理器上也支持8KiB。恐怕您不能仅仅假设块是4KiB。
marcelm

1
4k(默认值)是1k和2k的倍数,因此假设ext4使用4k是没有问题的。虽然xfs也将默认设置为4k,但它应该支持大于4k的bs(最大为64k),但是我只能创建这样的fs,如果没有ENOSYS,安装失败。而且无论如何,您不能假设任何事情-所有fs都不支持此功能,因此最好只说block = 4096,这样读者应该有一定的比例感,而不是任其浮动并让人们知道它可能是什么,或更糟糕的是,它是512字节,或者与vm页面大小有关。
mosvy

编辑(您说的通常是 4KiB)后,我完全同意!我的问题是,以前很容易将其读取为“块始终为4KiB”,这可能导致人们做出这种假设并编写错误的代码。
marcelm

9

由于当前所有文件系统都不需要将文件存储在连续的内存块中,

文件系统可能不需要将文件存储在连续的区域中(这实际上是非常不灵活的),但是通常文件存储在固定大小的块(或连续块的序列)中。这样做可以简化实现,并且块通常是基础设备的块大小的倍数。

因此,实现具有任意长度的块的插入将使文件系统格式和实现变得更加复杂,或者需要移动潜在的大量数据。这些都不是很好,并且可以在用户空间中基于文件系统API构建复杂的数据结构。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.