原子文件写操作(跨平台)

时间:2010-01-12 13:36:54

标签: java python file file-io

如何构建原子文件写操作?该文件由Java服务编写,并由python脚本读取 对于记录,读取远远大于写入。但是写入分批发生并且往往很长。文件大小相当于兆字节。

现在我的方法是:

  • 将文件内容写入临时文件中 同一目录
  • 删除旧文件
  • 将临时文件重命名为旧文件名。

这是正确的做法吗?如何避免旧文件被删除但新文件名尚未重命名的情况?

这些编程语言( python和java )是否提供锁定和避免这种情况的构造?

7 个答案:

答案 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请求。