如何构建原子文件写操作?该文件由Java服务编写,并由python脚本读取 对于记录,读取远远大于写入。但是写入分批发生并且往往很长。文件大小相当于兆字节。
现在我的方法是:
这是正确的做法吗?如何避免旧文件被删除但新文件名尚未重命名的情况?
这些编程语言( python和java )是否提供锁定和避免这种情况的构造?
答案 0 :(得分:10)
AFAIK没有。
原因是,为了使这种原子操作成为可能,必须以事务文件系统的形式支持OS。并且主流操作系统都没有提供事务性文件系统。
编辑 - 至少我对POSIX兼容系统有误。如果具有目标名称的文件已存在,则POSIX rename
系统调用执行原子替换...如@janneb所指出的那样。这应该足以以原子方式执行OP的操作。
然而,事实仍然是Java File.renameTo()
方法显然不保证是原子的,因此它不提供OP问题的跨平台解决方案。
编辑2 - 使用Java 7,您可以将java.nio.file.Files.move(Path source, Path target, CopyOption... options)
与copyOptions和ATOMIC_MOVE
一起使用。如果不支持(由OS /文件系统),则应该获得异常。
答案 1 :(得分:5)
至少在POSIX平台上,省略第3步(删除旧文件)。在POSIX中,文件系统中的重命名保证是原子的,并且在现有文件的顶部重命名将原子替换它。
答案 2 :(得分:3)
这是一个典型的生产者/消费者问题。您应该能够通过使用文件重命名来解决这个问题,这在POSIX系统上是原子的。
答案 3 :(得分:2)
在Linux,Solaris,Unix中这很容易。只需使用程序中的rename
()或mv
即可。这些文件需要位于同一个文件系统上。
在Windows上,如果您可以控制这两个程序,则可以执行此操作。 LockFileEx
。对于读取,请在lockfile上打开shared lock
。对于写入,请在lockfile上打开exclusive lock
。 Windows中的锁定很奇怪,因此我建议使用单独的锁定文件。
答案 4 :(得分:1)
答案 5 :(得分:1)
您可以尝试使用额外的文件来充当锁定,但我不确定这是否会成功。 (它会强制你在两边创建锁定检查和重试逻辑,java和python)
另一个解决方案可能是根本不创建文件,也许你可以让你的java进程监听端口并从那里而不是从文件提供数据?
答案 6 :(得分:1)
让python脚本请求服务的许可。当服务正在写入时,它会锁定文件。如果锁存在,服务将拒绝python请求。