c++ - Ifstream 在 OSX 上看不到新内容

标签 c++ macos file-io

我当前正在尝试读取另一个进程正在写入的 ifstream,然后将其发送到我的标准输出流。该文件可能非常大,因此我希望尽我所能,不必重新读取整个流。为此,我打开了一个 ifstream,并调用“clear”来删除 EoF 位。

在我们的 Linux 主机上,这工作正常(Arch、Debian、Ubuntu),但是在我们测试的 OSX 版本中,这不起作用。

我创建了尽可能小的测试文件来测试这个:

#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <thread>

int main() {
  auto temp_to_close = std::ofstream { std::string("stdout") };
  temp_to_close.close();

  auto stdout_stream = std::ifstream(std::string("stdout"));

  while (true) {
    stdout_stream.clear();
    std::cout << "--------------------------------------------" << "\n";
    std::cout << "EOF Stdout: " << (stdout_stream.eof() ? "T" : "F") << "\n";
    std::cout << "Fail Stdout: " << (stdout_stream.fail() ? "T" : "F") << "\n";
    std::cout << "--------------------------------------------" << "\n";

    std::string line;
    while (std::getline(stdout_stream, line)) {
      std::cout << line << "\n";
    }
    std::cout << "[" << (stdout_stream.eof() ? "T" : "F") << (stdout_stream.fail() ? "T" : "F") << "] line: " << line << "\n";
    std::cout.flush();
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }

  return 0;
}

在 Mac 和 Linux 上,我们遵循以下流程:

$ clang++ main.cpp -std=c++17 -Wall -o a.out
$ ./a.out
$ #open a new terminal window, cd to the same directory.
$ #next type: "echo "hello" >> stdout"
$ #switch back to the main window

在 Linux 上,这最终会在其他输出中打印:“hello”:

--------------------------------------------
EOF Stdout: F
Fail Stdout: F
--------------------------------------------
hello
[TT] line: 

这正是我们所期望的。然而在 Mac 上我们只能得到:

--------------------------------------------
EOF Stdout: F
Fail Stdout: F
--------------------------------------------
[TT] line: 

OSX 版本信息:

Mac OSX: v10.14.5
XCode Version: v10.2.1 (10E1001)
Clang++ --version:
Apple LLVM Version 10.0.1 (clang-1001.0.46.4)
Target: x85_64-apple-darwin-18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

编辑,正如 Eljay 在评论中提到的。添加eekg可以让所有平台看到内容:

stdout_stream.clear();
stdout_stream.seekg(stdout_stream.tellg());

最佳答案

clear() stdout_stream之后,还要sync()它:

stdout_stream.sync();

这是刷新任何底层流缓冲区的特定请求。

关于c++ - Ifstream 在 OSX 上看不到新内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56810779/

相关文章:

在 C 中仅将文件的一部分复制到新文件

c++ - 需要有关编程方法的建议

c++ - 类的端口结构

c++ - 调整我简单的 OpenGL/GLUT 窗口的大小会产生奇怪的线条

C++17 检查有效表达式

Android 模拟器使用 HAXM 卡住 OS X v10.9 (Mavericks)

swift - 使用动画隐藏 NSStackView 的 View 项

java - 在 Java 中使用 OS X 10.8 通知中心 (NSUserNotification)

c# - C#中使用XML文件存储数据

C# File.ReadAllLines 和 StreamReader.ReadLine 分割一些行