【问题标题】:How delete content of file after the last EOL?最后一次 EOL 后如何删除文件内容?
【发布时间】:2012-04-20 09:35:10
【问题描述】:

我有一些内部文件,只能附加到每个附加 \n 字符后添加到文件中。但从理论上讲,附加到文件可能会失败并损坏。这就是为什么每次打开文件时我都想在最后一个 EOL 之后寻找它的最后一个有效位置。此代码将执行此操作:

// Not using ios::app instead of ios::ate | ios::out because it will
// put print pointer to the EOF every time before writing.
fstream file(name.c_str(), ios::binary | ios::ate | ios::out | ios::in);
if(!file.is_open()) {
    cerr << "Error in oppening file " << name << endl;
    exit(EXIT_FAILURE);
} else {
    while(0 != file.tellp()) //if file is not empty
    {
        file.seekg(-1, ios_base::cur);
        if(0 == file.tellg() || file.get() == '\n') {
            break;
        }
        file.seekg(-1, ios_base::cur);
    }
    file.seekp(of.tellg());
}
//{1}
//Use file for appending to...

但是如果应该附加到文件的部分的长度小于从文件中最后一个 EOL 字符开始的部分的长度,它将无法正常工作。这就是为什么在{1} 位置我想删除从file.tellp() 到结尾的文件内容。

我该怎么做?

【问题讨论】:

    标签: c++ file fstream


    【解决方案1】:

    你不能,便携。不同的系统有不同的做事方式 这个,但通常只在系统文件句柄上。唯一保证 缩短文件的方法是将其复制到另一个文件中,而不是复制 你不想要的,然后删除原始文件并重命名新文件。

    如果它是一个文本文件(不是二进制文件),并且你在 windows 下,写一个 该位置的 0x1A 可能会起作用。 Unix下没有类似的东西, 但是。

    在您的情况下,仅覆盖结尾就足够了。如果更糟 更糟的是,您需要附加的内容还不足以 覆盖尾随数据,你可以尝试用一些东西覆盖它 无毒且易于识别,例如'\0'。 (正式地,写 像这样的东西,或者 0x1A,到一个文本文件是未定义的行为。 实际上,它会起作用。)

    (当我不得不解决类似的问题时,我采用了写作策略 记录开头的块的CRC;在阅读时,我忽略了 CRC 错误的任何内容。)

    【讨论】:

      【解决方案2】:

      没有可移植的方式来做到这一点(有关更全面的解释,请参阅 James Kanze 更好的答案)。

      如果您在 POSIX 系统上,则可以使用ftruncate(请参阅here)将文件的长度设置为特定长度。我不知道 C++ 等价物(有关更多信息,请参阅 this question

      【讨论】:

      • ftruncate 仅适用于 Unix。它也不接受流或FILE* 作为参数。
      • 这并不理想(正如我所说,我不知道 C++ 的)。我没有意识到这是一个仅限 POSIX 的命令。在 Windows 上,您似乎需要使用 _chsize_s 来实现相同的目的。
      • 在Windows下,对应的函数为SetEndOfFile。两者都需要系统句柄才能工作(而不是 filebufFILE*,因此 C++ 和 C 都不是)。
      • 好的,感谢您澄清这一点。我将编辑答案以反映不可移植性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 2014-11-12
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      相关资源
      最近更新 更多