使用 ofstream 将数据写入其文件后更新 ifstream 对象

Posted

技术标签:

【中文标题】使用 ofstream 将数据写入其文件后更新 ifstream 对象【英文标题】:Update ifstream object after data is written to its file using ofstream 【发布时间】:2015-01-06 21:11:36 【问题描述】:

在测试我的代码时,我遇到了一个问题,即当更多数据写入其文件时,ifstream 不会得到更新。所以这里是一个演示问题的示例代码:

    ifstream is(filename);
    string line;
    while (getline(is, line))
        cout << "line: " << line << endl;

    ofstream os(filename, ofstream::out | ofstream::app);
    string additional("additional");
    os << additional;
    os.flush();

    while (getline(is, line))
        cout << "line additional: " << line << endl;

没有额外的行被写入stdout,尽管它们被写入文件。 我没有使用 fstream 而不是几个 if/ofstream,因为我需要它来进行测试。

如何让ifstream“看到”文件中的变化?

更新:我使用clear 方法清除了这些位。它在我的带有 gcc 的 Ubuntu 机器上运行良好。但它不适用于我的带有 llvm 的 Mac OSX。你知道如何独立做平台吗?

【问题讨论】:

【参考方案1】:

您需要在第一次读取后在输入流上调用std::ios::clear。 当您读取整个文件时,它会在流中设置故障位并拒绝继续读取,即使文件实际上在此期间发生了更改。

ifstream is(filename);
string line;
while (getline(is, line))
    cout << "line: " << line << endl;

ofstream os(filename, ofstream::out | ofstream::app);
string additional("additional");
os << additional;
os.flush();

is.clear(); //< Now we can read again
while (getline(is, line))
    cout << "line additional: " << line << endl;

【讨论】:

哎呀,你是绝对正确的,我已经编辑了答案,谢谢! 谢谢!我设置了eofbit和failbit,所以基本上没关系,我只是清除它,它在ubuntu,gcc上工作正常。虽然它不适用于 Mac OSX,llvm。任何想法为什么?不幸的是,我无法在 Mac 上使用 lldb 对其进行调试。【参考方案2】:

当您第一次读取is 时到达文件末尾时,它会将eofbit 设置为流的内部错误状态。

您需要先清除它,然后才能继续阅读,方法是调用is.clear() 函数,该函数重置内部错误状态。

【讨论】:

关闭但eofbit 不是导致问题的位,而是failbit。但否则你的答案是正确的。【参考方案3】:

我认为原因是您使用“ofstream::out”打开了输出流文件

ofstream os(filename, ofstream::out | ofstream::app);

现在,“ofstream::out”会在打开文件后立即截断文件。也就是说,文件的所有先前内容一旦打开就会被删除。请尝试改用这个:

ofstream os(filename, ios::app);

【讨论】:

std::ios_base::out 始终使用,无论是否指定为开放模式。 std::ios_base::app 禁止销毁内容。

以上是关于使用 ofstream 将数据写入其文件后更新 ifstream 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中将字节写入 ofstream

大约 2Gb 后 C++ ofstream 写入性能下降

C++ ofstream向文件写数据?

❥关于C++之写入/读取文本文件

使用 ofstream 写入 txt 文件时强制编码

std::ofstream,写入前检查文件是不是存在