典型的系统调用接口是否允许减小文件的大小(而不用其他inode替换它)?


9

有没有一种方法可以open()使文件缩小?当然,可以以追加模式打开它们,也可以寻找结尾并进行书写以使它们增长。但是,据我所知,没有方法可以通过典型的unix风格的系统调用接口来缩小文件。

据我所知,这样做的唯一方法是通过创建一个新的较短文件rename()代替旧文件来伪造它。

我只想确认,因为我看到一个答案,它暗示可以使直接在文件上工作的文件编辑器成为可能,而不需要经过制作新文件并将其重命名的过程。

我一直认为libc和unix风格的系统调用接口中的文件api不允许文件缩小以简化文件系统的实现,并且可能避免使用可能导致碎片化的使用模式。


2
只需以fopen“ w”(或“ w +”)模式打开文件,它将自动将其截断为零长度。还是说要缩小到非零大小以保留某些旧内容?
Wyzard

4
仅供参考,open()并且openat()已经有一个截断标志,O_TRUNC因此从技术上讲,它的确会导致文件缩小-即完全缩小-而不会更改inode。最著名的例子是command > file.txt,如果文件存在,文件将被截断。如果继续运行stracebash -c 'true > /dev/null'则会openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666)在输出中看到。当然,对于可变大小的截断,您需要truncate()syscall。让我知道是否要将此作为实际答案而不是评论。
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy我正在考虑缩小到任意大小。我赞成David Foerster的答案,因为它回答了一部分问题,但鉴于伊卡洛斯的观点,我不接受。我会把它当作是和否的答案,而伊卡洛斯的答案已经表明,真正的答案是“是”。
JoL

Answers:


22

man -s 2 ftruncate

DESCRIPTION
   The  truncate()  and  ftruncate()  functions cause the regular file
   named by path or referenced by fd to be truncated to a size of precisely
   length bytes.

...

CONFORMING TO
   POSIX.1-2001, POSIX.1-2008, 4.4BSD, SVr4 (these calls first appeared in 4.2BSD).

它接着说,如果使用ftruncate,则必须已打开文件进行写入,如果使用truncate,则该文件必须可写。


附加到文件会导致操作系统首先truncate适应新文件的大小,然后 适应新文件的大小write。所以truncate就是你要找的系统调用。
mgarciaisaia

1
在Linux上,还看到fallocate(FALLOC_FL_COLLAPSE_RANGE)
斯特凡Chazelas

2

open(2)系统调用接受O_TRUNC,可以减小文件大小的标志:

O_TRUNC–如果该文件存在并且是常规文件,并且已成功打开O_RDWR或文件O_WRONLY,则其长度应被截断为0,并且模式和所有者应保持不变。它对FIFO特殊文件或终端设备文件无效。它对其他文件类型的影响是实现定义的。O_TRUNC不使用O_RDWR或的使用结果O_WRONLY是不确定的。

当程序旨在完全覆盖文件内容时,经常使用它。一个示例是shell的文件重定向操作符,如中所述command > file

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.