简体   繁体   English

java.io.File.createNewFile()是否在网络文件系统中是原子的?

[英]Is java.io.File.createNewFile() atomic in a network file system?

EDIT : Well, I'm back a bunch of months later, the lock mechanism that I was trying to code doesn't work, because createNewFile isn't reliable on the NFS. 编辑:嗯,我回来了几个月后,我试图编码的锁机制不起作用,因为createNewFile在NFS上不可靠。 Check the answer below. 检查下面的答案。


Here is my situation : I have only 1 application which may access the files, so I don't have any constraint about what other applications may do, but the application is running concurrently on several servers in the production environment for redundancy and performance purposes (a couple of machines are hosting each a couple of JVM with our apps). 这是我的情况:我只有一个可以访问文件的应用程序,因此我对其他应用程序可能执行的操作没有任何限制,但是为了冗余和性能目的,应用程序在生产环境中的多个服务器上同时运行(有几台机器正在使用我们的应用程序托管每个JVM。

Basically, what I need is to put some kind of flag in a folder to tell the other instances to leave this folder alone as another instance is already dealing with it. 基本上,我需要的是在文件夹中放置某种标志,以告诉其他实例单独保留此文件夹,因为另一个实例已经在处理它。


Many search results are telling to use FileLock to achieve this, but I checked the Javadoc, and from my understanding it will not help much, since it's using the hosting OS's locking possibilities. 许多搜索结果都告诉我们使用FileLock来实现这一目标,但是我检查了Javadoc,根据我的理解它不会有太大帮助,因为它使用托管操作系统的锁定可能性。 So I doubt that it will help much since there are different hosting machines. 所以我怀疑它会有很大帮助,因为有不同的托管机器。

This question covers a similar subject : Java file locking on a network , and the accepted answer is recommending to implement your own kind of cooperative locking process (using the File.createNewFile() as asked by the OP). 这个问题涵盖了一个类似的主题: 网络上的Java文件锁定 ,并且接受的答案是建议实现您自己的协作锁定过程(使用OP提出的File.createNewFile() )。


The Javadoc of File.createNewFile() says that the process is atomically creating the file if it doesn't already exist. File.createNewFile()的Javadoc表示如果该文件尚不存在,该过程将自动创建该文件。 Does that work reliably in a network file system ? 这在网络文件系统中是否可靠?

I mean, how is it possible with the potential network lag to do both existence check and creation simultaneously ? 我的意思是,潜在的网络延迟如何同时进行存在检查和创建? :

The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file. 检查文件是否存在以及文件的创建(如果不存在)是针对可能影响文件的所有其他文件系统活动的原子操作。

No, createNewFile doesn't work properly on a network file system. 不, createNewFile在网络文件系统上无法正常工作。

Even if the system call is atomic, it's only atomic regarding the OS, and not over the network. 即使系统调用是原子的,它只是关于操作系统的原子,而不是通过网络。 Over the time, I got a couple of collisions, like once every 2-3 months (approx. once every 600k files). 随着时间的推移,我遇到了几次碰撞,比如每2-3个月一次(大约每600k文件一次)。

The thing that happens is my program is running in 6 separates instances over 2 separate servers, so let's call them A1,A2,A3 and B1,B2,B3. 发生的事情是我的程序在2个独立的服务器上运行6个实例,所以让我们称它们为A1,A2,A3和B1,B2,B3。
When A1, A2, and A3 try to create the same file, the OS can properly ensure that only one file is created, since it is working with itself. 当A1,A2和A3尝试创建相同的文件时,操作系统可以正确地确保只创建一个文件,因为它正在使用它自己。
When A1 and B1 try to create the same file at the same exact moment, there is some form of network cache and/or network delays happening, and they both get a true return from File.createNewFile() . 当A1和B1尝试在同一时刻创建相同的文件时,会出现某种形式的网络缓存和/或网络延迟,并且它们都从File.createNewFile()获得true返回。
My code then proceeds by renaming the parent folder to stop the other instances of the program from unnecessarily trying to process the folder and that's where it fails : 然后我的代码通过重命名父文件夹来停止程序的其他实例,从而不必要地尝试处理文件夹,这就是它失败的地方:

  • On A1, the folder renaming operation is successful, but the lock file can't be removed, so A1 just lets it like that and keeps on processing new incoming folders. 在A1上,文件夹重命名操作成功,但无法删除锁定文件,因此A1只是让它这样,并继续处理新的传入文件夹。
  • On B1, the folder renaming operation ( File.renameTo() , can't do much to fix it) gets stuck in a infinite loop because the folder was already renamed (also causing a huge I/O traffic according to my sysadmin), and B1 is unable to process any new file until the program is rebooted. 在B1上,文件夹重命名操作( File.renameTo() ,无法修复它)陷入无限循环,因为文件夹已经重命名(根据我的系统管理员也导致巨大的I / O流量),在重新启动程序之前,B1无法处理任何新文件。

The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file. 检查文件是否存在以及文件的创建(如果不存在)是针对可能影响文件的所有其他文件系统活动的原子操作。

That can be implemented easily via the open() system call or its equivalents in any operating system I have ever used. 这可以通过open()系统调用或我曾经使用过的任何操作系统中的等价物轻松实现。

I mean, how is it possible with the potential network lag to do both existence check and creation simultaneously ? 我的意思是,潜在的网络延迟如何同时进行存在检查和创建?

There is a difference between simultaneously and atomically . 同时原子之间存在差异。 Java doc is not saying anything about this function being a set of two simultaneous actions but two actions designed to work in atomic way. Java doc并没有说这个函数是一组两个同步动作,而是两个旨在以原子方式工作的动作。 If this method is built to do two operations atomically than means file will never be created without checking file existence first and if file gets created by current call then it means there were no files present and if file doesn't get created that means there was already a file by that name. 如果构建此方法以原子方式执行两个操作而不是在没有先检查文件存在的情况下永远不会创建文件,并且如果文件由当前调用创建,则表示没有文件存在且文件未创建意味着存在已经是该名称的文件。

I don't see a reason to doubt function being atomic or working reliably despite call being on network or local disk. 尽管呼叫在网络或本地磁盘上,但我没有理由怀疑功能是原子的还是可靠的。 Local call is equally unreliable - so many things can go wrong in an IO. 本地呼叫同样不可靠 - 在IO中可能出现很多问题。

What you have to doubt is when trying to use empty file created by this function as a Lock as explained D-Mac's answer for this question and that is what explicitly mentioned in Java Doc for this function too. 当你尝试使用这个函数创建的空文件作为Lock时,你不得不怀疑这是D-Mac对这个问题的回答, 也是Java Doc中为这个函数明确提到的。

You are looking for a directory lock and empty files working as a directory lock ( to signal other processes and threads to not touch it ) has worked quite well for me provided due care is taken to write logic to check for file existence,lock file clean up and orphaned locks. 你正在寻找一个目录锁和空文件作为目录锁(以指示其他进程和线程不接触它)已经很好地为我工作提供了应当小心写逻辑来检查文件是否存在,锁定文件清理向上和孤立的锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM