java 原子文件写入操作(跨平台)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2049247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Atomic file write operations (cross platform)
提问by Quintin Par
How do I build up an atomic file write operation? The file is to be written by a Java service and read by python scripts.
For the record, reads are far greater than writes. But the write happens in batches and tend to be long. The file size amounts to mega bytes.
如何建立原子文件写入操作?该文件将由 Java 服务编写并由 python 脚本读取。
就记录而言,读取远远大于写入。但是写入是分批进行的,而且往往很长。文件大小为兆字节。
Right now my approach is:
现在我的做法是:
- Write file contents to a temp file in same directory
- Delete old file
- Rename temp file to old filename.
- 将文件内容写入同一目录中的临时文件
- 删除旧文件
- 将临时文件重命名为旧文件名。
Is this the right approach? How can avoid conditions where the old file is deleted but the new filename is yet to be renamed?
这是正确的方法吗?如何避免旧文件被删除但新文件名尚未重命名的情况?
Do these programming languages (python and java) offer constructs to lock and avoid this situation?
这些编程语言(python 和 java)是否提供了锁定和避免这种情况的构造?
采纳答案by Stephen C
AFAIK no.
AFAIK 没有。
And the reason is that for such an atomic operation to be possible, there has to be OS support in the form of a transactional file system. And none of the mainstream operating system offer a transactional file system.
原因是为了使这样的原子操作成为可能,必须以事务文件系统的形式提供操作系统支持。并且主流操作系统都没有提供事务文件系统。
EDIT- I'm wrong for POSIX-compliant systems at least. The POSIX renamesyscall performs an atomic replace if a file with the target name already exists ... as pointed out by @janneb. That should be sufficient to do the OP's operation atomically.
编辑- 至少我对符合 POSIX 的系统是错误的。rename如果具有目标名称的文件已经存在,POSIX系统调用将执行原子替换......正如@janneb 所指出的。这应该足以以原子方式执行 OP 的操作。
However, the fact remains that the Java File.renameTo()method is explicitly notguaranteed to be atomic, so it does not provide a cross-platform solution to the OP's problem.
然而,事实仍然是 JavaFile.renameTo()方法明确不能保证是原子的,因此它没有为 OP 的问题提供跨平台的解决方案。
EDIT 2- With Java 7 you can use java.nio.file.Files.move(Path source, Path target, CopyOption... options)with copyOptions and ATOMIC_MOVE. If this is not supported (by the OS / file system) you should get an exception.
编辑 2- 使用 Java 7,您可以使用java.nio.file.Files.move(Path source, Path target, CopyOption... options)copyOptions 和ATOMIC_MOVE. 如果这不受支持(操作系统/文件系统),您应该得到一个例外。
回答by janneb
At least on POSIX platforms, leave out step 3 (delete old file). In POSIX, rename within a filesystem is guaranteed to be atomic, and renaming on top of an existing file replaces it atomically.
至少在 POSIX 平台上,省略第 3 步(删除旧文件)。在 POSIX 中,文件系统内的重命名保证是原子的,并且在现有文件的顶部重命名会原子地替换它。
回答by gruszczy
It's a classic producer/consumer problem. You should be able to solve this by using file renaming, which is atomic on POSIX systems.
这是一个经典的生产者/消费者问题。您应该能够通过使用文件重命名来解决这个问题,这在 POSIX 系统上是原子的。
回答by unixman83
In Linux, Solaris, Unix this is easy. Just use rename() from your program or mv. The files need to be on the same filesystem.
在 Linux、Solaris、Unix 中,这很容易。只需rename在您的程序中使用() 或mv. 这些文件需要在同一个文件系统上。
On Windows, this is possible if you can control both programs. LockFileEx. For reads, open a shared lockon the lockfile. For writes, open an exclusive lockon the lockfile. Locking is weird in Windows, so I recommend using a separate lock filefor this.
在 Windows 上,如果您可以控制这两个程序,这是可能的。LockFileEx. 对于读取,shared lock在锁定文件上打开 a 。对于写操作,exclusive lock在锁文件上打开一个。锁定在 Windows 中很奇怪,因此我建议为此使用单独的锁定文件。
回答by Ron
Have the python scripts request permission from the service. While the service is writing it would place a lock on the file. If the lock exists, the service would reject the python request.
让 python 脚本从服务请求权限。在服务写入时,它会锁定文件。如果锁存在,服务将拒绝 python 请求。
回答by St.Shadow
回答by Simon Groenewolt
You could try and use an extra file to act as a lock, but I'm not sure if that will work out ok. (It would force you to create lock-checking and retry logic at both sides, java and python)
您可以尝试使用额外的文件作为锁,但我不确定这是否可行。(它会迫使你在双方,java 和 python 上创建锁检查和重试逻辑)
Another solution might be to not create files at all, maybe you could make your java process listen on a port and serve data from there rather than from a file?
另一种解决方案可能是根本不创建文件,也许您可以让您的 java 进程侦听端口并从那里而不是从文件中提供数据?

