在截断模式下打开文件时的行为

Behavior when opening file in truncate mode

本文关键字:文件 模式      更新时间:2023-10-16

我正在使用C文件描述符处理文件IO。问题是我正在尝试创建一个可以容纳以下事件序列的通用类:

  1. 断模式下的现有文本文件(即清除其当前内容)。
  2. 文本写入此文件
  3. 刚刚编写的文本被清除。
  4. 此后,新文本将写入文件。

问题的简化重现编码如下:

//1.
int fd = open("/path/to_file/file.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);
//2.
const char* text = "12345";
write(fd, static_cast<const void*>(text), 5);
//3.
ftruncate(fd, 0);
//4.
const char* new_text = "678";
write(fd, static_cast<const void*>(new_text), 3);

输出是文件开头有 5 个,后跟字符串678,所以看起来像678

看来ftruncate认为我实际上是在尝试将文件扩展 5 个字节,如下所述:https://linux.die.net/man/2/ftruncate

如果文件以前大于此大小,则额外的数据将丢失。如果文件以前较短,则会对其进行扩展,并且扩展部分读取为空字节 ('\0')。

但是,如果我使用O_APPEND标志打开文件,那么一切正常。这个问题有什么解决方案吗?

这是您的代码正在逐步执行的操作:

//1.
int fd = open("/path/to_file/new.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);

文件被创建或截断,大小为零,打开的文件描述符的当前偏移量为 0。

//2.
const char* text = "12345";
write(fd, static_cast<const void*>(text), 5);

12345字符写入文件,当前偏移量为 5

//3.
ftruncate(fd, 0);

文件的长度现在为零。打开的文件描述符的当前偏移量为 5。

//4.
const char* new_text = "678";
write(fd, static_cast<const void*>(new_text), 3);

字符678当前偏移量 5 开始写入文件。