如何从另一个进程连续写入的文件中可靠地读取数据?

时间:2019-01-08 09:49:12

标签: linux file

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

我可以想到的解决此问题的方法是,编写器进程也可以写入相应的校验和文件。现在,读取器进程将必须同时读取文件及其校验和文件。如果计算出的校验和不匹配,则读取器进程将重复该过程,直到计算出的校验和匹配为止。这样,现在它将知道它已读取正确的数据。

或者也许更好的解决方案是在特定时间段之后(比写入过程的写入间隔小得多)读取文件两次,然后查看读取的数据是否匹配。

第三种方法可能是在文件末尾写入一些魔术数据,以便读取过程知道,如果它在末尾对魔术数据进行了加密,则读取了整个文件。

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

2 个答案:

答案 0 :(得分:2)

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

mkfifo ./jsonoutput

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

只要编写器在编写每个JSON之后定期关闭并重新打开文件,阅读器就会获得EOF并处理输入。

但是,如果不是这种情况,读者将继续阅读,而作家将继续写作。如果程序并非旨在处理此类数据流,则它们可能永远不会处理数据,并且程序将挂起。

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

答案 1 :(得分:2)

每次创建一个新文件,并在完全写入新文件后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()进行文件存储-它无法保留并打开文件上的文件描述符,并尝试以{ {1}}调用取消链接原始文件,并将其替换为一个全新的文件。