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

时间:2017-04-11 12:08:31

标签: c++ file-io truncate

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

  1. 截断模式下的现有文本文件(即清除其当前内容)。
  2. 文本将写入此文件
  3. 刚刚写好的文字被清除。
  4. 此后将新文本写入文件。
  5. 问题的简化再现如下:

    //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

      

    如果之前的文件大于此大小,则额外数据将丢失。如果先前的文件较短,则会扩展,扩展部分读取为空字节(&#39; \ 0&#39;)。

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

1 个答案:

答案 0 :(得分:3)

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

//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 开始写入文件。