C++连续读取文件

标签 c++ file-io

我有一个生产者/消费者设置:我们的客户端向我们提供服务器处理的数据,并且我们的客户端通过不断写入文件来向我们的服务器提供数据。我们的服务器使用 inotify 来查找任何文件修改,并处理新数据。

问题:服务器中的文件读取器的缓冲区大小为 4096。我有一个模拟上述情况的单元测试。测试不断写入打开的文件,文件读取器不断尝试读取进程。但是,我注意到在读取第一条记录(远小于 4096)后,在 ifstream 对象中设置了一个错误标志。这意味着任何新到达的数据都不会被处理。一个简单的解决方法似乎是在每次读取后调用 ifstream::clear ,这确实解决了问题。但是,这是怎么回事?这是正确的解决方案吗?

最佳答案

首先,根据您的系统,可能会或可能不会读取另一个进程写入的文件:在 Windows 上,打开文件时的正常设置会进行独占访问。我对Window了解不够,无法判断是否还有其他设置。在 POSIX 系统上,具有适当权限的文件可以打开以供不同进程读取和写入。从听起来你正在使用 Linux,即遵循 POSIX 规范的东西。

不过,在更改时轮询文件的方法并不完全理想:正如您所注意到的,每次到达当前文件的末尾时都会收到“错误”。实际上,到达文件末尾并不是真正的错误,但尝试解码超出文件末尾的内容是一个错误。此外,读取超出文件末尾的内容仍会设置 std::ios_base::eofbit,因此流不会是 good()。如果您坚持使用这种方法,那么除了读取到文件末尾并以某种方式处理不完整的读取之外,没有太多选择。

但是,如果您可以控制文件的创建,则可以使用一个简单的技巧:您可以将其创建为 mkfifo 来创建一个 命名管道使用写入程序将写入的文件名:在 POSIX 系统上打开文件时,如果已有文件,则不会创建新文件,而是使用现有文件。好吧,文件或其他任何由文件名寻址的内容(除了文件和命名管道之外,您还可能会看到目录、字符或 block 特殊设备,以及可能的其他设备)。

命名管道是一种奇怪的野兽,旨在让两个进程相互通信:一个进程写入一端的内容可以在另一端由另一个进程读取!命名管道本身没有任何内容,即,如果您需要文件的内容以及与另一个进程的通信,您可能需要将内容复制到某个地方。打开一个命名管道进行读取,只要到达文件的当前末尾,该管道就会阻塞,即最初读取会阻塞,直到有写入者为止。同样,对命名管道的写入将被阻塞,直到有读取器为止。一旦有两个进程通信,在另一个进程退出后,在读取或写入命名管道时,另一端将收到错误。

关于C++连续读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12535381/

相关文章:

c++ - 这个 C++ 多重继承是否正确?

c++ - 为什么找不到 DirectX 模板?

java - 写入控制台和文本文件

java - 将 JTextPane 的内容保存到普通文本文件失败

java检查特定位置的管理员权限

sas - 使用 SAS 宏从 Windows 目录通过管道传输文件名列表

java - 从 -main 调用时,Clojure 函数不将输出写入文件

c++ - 类型在 SFINAE 中未继承以进行多重继承?

c++ - 使用 OpenCV 特征检测器匹配热成像/非热成像图像

c++ - 为什么基于 int 的访问对 std::get(std::tuple) 不起作用?