如何删除最后一个EOL后的文件内容?

时间:2012-04-20 09:35:10

标签: c++ file fstream

我有一些内部文件,只能在每个附加的\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()到结尾的文件内容。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

没有可行的方法可以做到这一点(请参阅James Kanze更好的答案以获得更全面的解释)。

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

答案 1 :(得分:1)

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

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

在你的情况下,不只是覆盖结束就足够了。如果更糟 变得更糟,你需要追加的东西是不够的 覆盖尾随数据,您可能会尝试用某些东西覆盖它 像'\0'一样,很容易辨认。 (正式,写作 像这样的东西,或0x1A,到文本文件是未定义的行为。 实际上,它会起作用。)

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