因此,我处于一个进程正在连续(每隔几秒钟)将数据写入文件(不追加)的情况。数据采用json的形式。现在,另一个过程必须定期读取此文件。现在可能是在写入过程正在写入文件时,读取过程正在读取它。
我可以想到的解决此问题的方法是,编写器进程也可以写入相应的校验和文件。现在,读取器进程将必须同时读取文件及其校验和文件。如果计算出的校验和不匹配,则读取器进程将重复该过程,直到计算出的校验和匹配为止。这样,现在它将知道它已读取正确的数据。
或者也许更好的解决方案是在特定时间段之后(比写入过程的写入间隔小得多)读取文件两次,然后查看读取的数据是否匹配。
第三种方法可能是在文件末尾写入一些魔术数据,以便读取过程知道,如果它在末尾对魔术数据进行了加密,则读取了整个文件。
您怎么看?这些解决方案是否可行,或者有更好的方法来实现这一目标?
答案 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}}调用取消链接原始文件,并将其替换为一个全新的文件。