【发布时间】:2023-03-07 08:55:01
【问题描述】:
我正在使用 C 文件描述符处理文件 IO。问题是我正在尝试创建一个可以容纳以下事件序列的通用类:
- 截断模式下的现有文本文件(即清除其当前内容)。
- 文本写入此文件
- 刚刚写入的文字被清除。
- 随后将新文本写入文件。
问题的简化再现代码如下:
//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个\0,后面跟着字符串678,所以看起来像\0\0\0\0\0678。
ftruncate 似乎认为我实际上是在尝试将文件扩展 5 个字节,如下所述:https://linux.die.net/man/2/ftruncate
如果之前的文件大于这个大小,多余的数据就会丢失。如果文件先前较短,则将其扩展,扩展部分读取为空字节 ('\0')。
但如果我使用O_APPEND 标志打开文件,那么一切正常。这个问题有什么解决办法吗?
【问题讨论】:
-
同样来自
man ftruncate:“文件偏移量没有改变。” -
我不明白在追加模式下打开时偏移问题是如何解决的 --> 添加更多文本 --> 清除所有内容 --> 添加新文本。无需更改文件指针即可正常工作。
-
追加模式不允许在文件内四处寻找。因此,在这种模式下,offet 似乎会自动调整以实现后一个约束。
-
没有C/C++语言! C 和 C++ 这两种不同的语言有不同的方式来访问文件。您显然在 C++ 代码中使用了 C 方式(实际上是 POSIX 函数,而不是 C 标准)。所以这不是 C 代码。