据我了解,对于操作文件,Linux 中只有 sys_write 系统调用,它会覆盖文件内容(或扩展它,如果在最后)。
为什么 Linux 中没有用于在文件中插入或删除内容的系统调用?
由于当前所有文件系统都不要求将文件存储在连续的内存块中,因此应该可以实现有效的实现。 (文件会变得支离破碎。)
由于文件系统具有“写入时复制”或“透明文件压缩”等功能,当前插入内容的方式似乎效率非常低。
答案1
在最近的 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
将被追加到该位置offset
,并且该文件将len
减小字节数。[...]
增加文件空间
指定
FALLOC_FL_INSERT_RANGE
标志(自 Linux 4.1 起可用)可mode
通过在文件大小中插入一个洞来增加文件空间,而不会覆盖任何现有数据。该洞将从 处开始offset
并持续len
字节。当在文件内插入空洞时,从 处开始的文件内容offset
将向上移动(即,到更高的文件偏移量)len
字节。在文件中插入一个洞会增加文件大小len
字节。
答案2
由于目前所有的文件系统都不要求文件存储在连续的内存块中,
文件系统可能不需要将文件存储在连续区域中(这确实非常不灵活),但通常文件存储在固定大小的块(或连续块的序列)中。这样做可以简化实现,并且块通常是底层设备块大小的倍数。
因此,实现任意长度的块插入将使文件系统格式和实现变得更加复杂,或者需要移动潜在的大量数据。这些都不是很好,复杂的数据结构可以在文件系统 API 之上的用户空间中构建。