【问题标题】:How to reliably read data from a file which is being continuously written by another process?如何可靠地从另一个进程连续写入的文件中读取数据?
【发布时间】:2019-06-02 23:42:46
【问题描述】:

因此,我处于一个进程连续(每隔几秒钟)将数据写入文件(不附加)的情况。数据为json格式。现在另一个进程必须定期读取这个文件。现在可能是读取过程在写入过程写入文件时读取它。

我能想到的解决这个问题的方法是让写入进程也写入相应的校验和文件。读取器进程现在必须读取文件及其校验和文件。如果计算的校验和不匹配,读取器进程将重复该过程,直到计算的校验和匹配。这样,现在它就知道它已经读取了正确的数据。

或者也许更好的解决方案是在一定时间后(远小于写入过程的写入间隔)读取文件两次,并查看读取的数据是否匹配。

第三种方法可能是在文件末尾写入一些魔术数据,以便读取过程知道它已经读取了整个文件,如果它在末尾遇到了魔术数据。

你怎么看?这些解决方案是否可行,或者有更好的方法来实现吗?

【问题讨论】:

  • writer进程的代码你写吗?如果是,您可以尝试制作一个信号量文件,当您想读取时,您正在“锁定”该文件,并且写入进程在读取之前无法写入。
  • 我认为这需要锁定,正如@PierreEmmanuelLallemant 所说。您可以利用flock。
  • 检查this thread
  • 您需要实现锁定。

标签: linux file


【解决方案1】:

每次创建一个完整的新文件,并在完全写入后rename() 新文件:

如果 newpath 已经存在,它将被原子替换,这样 没有另一个进程试图访问 newpath 会发现它丢失了。 ...

文件的某些副本将始终存在,并且始终完整且正确:

所以,而不是

writeDataFile( "/path/to/data/file.json" );

然后试图弄清楚在阅读器进程中要做什么,您只需这样做

writeDataFile( "/path/to/data/file.json.new" );
rename( "/path/to/data/file.json.new", "/path/to/data/file.json" );

不需要锁定,也不需要读取文件和计算校验和并希望它是正确的。

唯一的问题是任何读取器进程在每次需要读取最新副本时都必须 open() 文件 - 它无法保留和打开文件上的文件描述符并尝试读取 rename() 的新内容调用取消链接原始文件并用一个全新的文件替换它。

【讨论】:

  • 这是一个非常聪明的解决方案:)!
  • @MetallicPriest 谢谢。只需确保这两个文件在同一个文件系统中。否则,如果您没有在 C 中进行编码并直接进行 rename() 调用,那么所谓的 rename 或类似内容实际上可能 复制 文件内容,这不是您想要的.你不想做 Linux mv 实用程序所做的事情,例如,尝试 rename() 系统调用,如果失败,则回退到复制文件内容。
【解决方案2】:

如果您想保证阅读器始终获取所有数据,请考虑使用名称管道。

mkfifo ./jsonoutput

然后设置一个程序写入,另一个程序读取这个文件./jsonoutput。

只要写入器在写入每个 JSON 后定期关闭和重新打开文件,读取器就会得到一个 EOF 并处理输入。

但是,如果不是这样,读者将继续阅读,而作者将继续写作。如果程序不是为处理这样​​的数据流而设计的,那么它们可能永远不会处理数据并且程序将挂起。

如果是这种情况,那么您可以编写一个程序,从一个命名管道读取,直到它获得完整的 JSON,然后通过第二个命名管道将其刷新到最终程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2012-10-22
    相关资源
    最近更新 更多