java 为什么 'File.exists' 返回 true,即使 NIO 'Files' 类中的 'Files.exists' 返回 false
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30520179/
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
Why does 'File.exists' return true, even though 'Files.exists' in the NIO 'Files' class returns false
提问by The Coordinator
I am trying to determine if a file exists in a network folder:
我正在尝试确定网络文件夹中是否存在文件:
// File name is "\QWERTY\folder\dir\A123456.TXT"
Path path = Paths.get("\\QWERTY\folder\dir\A123456.TXT")
Using NIO Files
:
使用蔚来Files
:
Files.exists(path) == false
Using File
:
使用File
:
path.toFile().exists() == true
Using File
seems to be the correct one according to our tests. Why does File
work better than Files
?
File
根据我们的测试,使用似乎是正确的。为什么File
比 效果更好Files
?
So, which is it? Can't be both!
那么,它是哪个?不能两者兼得!
But wait, there is also Files.notExists(path)
.
但是等等,还有Files.notExists(path)
。
When the network share file actually exists
当网络共享文件实际存在时
Files.exists(path): false
Files.notExists(path): false
path.toFile().exists(): true
When the network share file actually does notexist
当网络共享文件实际上并不会存在
Files.exists(path): false
Files.notExists(path): true
path.toFile().exists(): false
Another equally insane way of looking at the three results above
查看上述三个结果的另一种同样疯狂的方式
boolean exists = Files.exists(path) || !Files.notExists(path)
boolean notExists = Files.notExists(path) || !Files.exists(path)
boolean oldFashionedExists = path.toFile().exists()
:smileyFace:
:笑脸:
Environment and Comments
环境和评论
The program is running on a Windows 8.1 Pro 32 bit machine (OS and machine) and checking on a network share from a Windows 2008 R2 (32 bit) machine.
该程序在 Windows 8.1 Pro 32 位机器(操作系统和机器)上运行,并检查来自 Windows 2008 R2(32 位)机器的网络共享。
To determine that Files.exists was failed, I installed a WatchService to monitor the folder and saw that the file did exist when Files.exists was checking. I then logged as both methods and found File.exists to be the correct one.
为了确定 Files.exists 失败,我安装了一个 WatchService 来监视文件夹,并在 Files.exists 检查时看到该文件确实存在。然后我用这两种方法登录,发现 File.exists 是正确的。
Now, in my code I have the check as Files.exists(path) || path.toFile().exists()
.
现在,在我的代码中,我将检查作为Files.exists(path) || path.toFile().exists()
.
Kinda seems stupid to have to do both. Probably could just get away with the later. Just trying to give the engineers over at Oracle the benefit of the doubt, but the whole thing is rather silly that they report different.
两者兼得似乎有点愚蠢。可能只是后来逃脱了。只是试图让甲骨文的工程师从怀疑中受益,但整个事情相当愚蠢,他们报告的不同。
Also, I don't care if 'exists' is immediately outdated. I just want to know if the file exists at the instant that we are checking. I've never come across this -- we just spent 30 hours between me and another developer trying to figure out why our programs are not interfacing because of this 'feature'.
另外,我不在乎“存在”是否立即过时。我只想知道在我们检查的那一刻文件是否存在。我从来没有遇到过这种情况——我们只是在我和另一位开发人员之间花了 30 个小时试图弄清楚为什么我们的程序因为这个“功能”而没有接口。
Meditate on this a while
沉思一会儿
File.exists(): Returns true if and only if the file or directory denoted by this abstract pathname exists; false otherwise.
Files.exists(): Returns true if the file exists; false if the file does not exist or its existence cannot be determined.
File.exists():当且仅当此抽象路径名表示的文件或目录存在时才返回真;否则为假。
Files.exists():如果文件存在则返回true;如果文件不存在或无法确定其存在,则为 false 。
That cracks me up! "if and only if the file or directory denoted by this abstract pathname exists; false otherwise" is at odds with "true if the file exists; false if the file does not exist or its existence cannot be determined"
这让我崩溃!“当且仅当此抽象路径名表示的文件或目录存在;否则为假”与“如果文件存在则为真;如果文件不存在或无法确定其存在则为假”不一致
So, how still can File.exists
be true if "the existence cannot be determined"? Obviously, the existence can be (and is being) determined by File but not by Files.
那么,File.exists
“存在不能确定”又怎么可能是真的呢?显然,存在可以(并且正在)由文件而不是由文件确定。
回答by paxdiablo
As to why there may be a difference between the two, contrast their documentation:
至于为什么两者之间可能存在差异,请对比他们的文档:
File.exists(): Returns true if and only if the file or directory denoted by this abstract pathname exists; false otherwise.
Files.exists(): Returns true if the file exists; false if the file does not exist or its existence cannot be determined.
File.exists():当且仅当此抽象路径名表示的文件或目录存在时返回真;否则为假。
Files.exists():如果文件存在则返回true;如果文件不存在或无法确定其存在,则为 false 。
That could possiblyexplain the difference between the two, perhaps the Files
one is having troubles ascertaining the existence of the file.
这可能可以解释两者之间的区别,也许Files
是无法确定文件的存在。
For example, under Linux, it's possible to set up directory and file permissions in such a way that you can open a file that exists but cannot seethat it exists (by taking away read permission on the directory the file is in while leaving the file permissions more open).
例如,在 Linux 下,可以设置目录和文件权限,这样您可以打开一个存在但看不到它的文件(通过在离开文件的同时取消对该文件所在目录的读取权限)权限更开放)。
As per more of Oracle's documentation, Files.exists()
only returns true
if the file is verified to exist.
根据Oracle 的更多文档,Files.exists()
只有true
在验证文件存在时才返回。
A return value of false
does notmean it doesn't exist.
的返回值false
不不意味着它不存在。
They suggest you use both exists()
and notExists()
to cover the three possibilities, something like:
他们建议您同时使用exists()
和notExists()
来涵盖三种可能性,例如:
if (Files.exists(fspec)) {
System.out.println("It exists!");
else if (Files.notExists(fspec)) {
System.out.println("It does not exist!");
else
System.out.println("I have no idea!");
That covers the three possibilities of file state covered in that link above:
这涵盖了上述链接中涵盖的文件状态的三种可能性:
- The file is verified to exist.
- The file is verified to not exist.
- The file's status is unknown. This result can occur when the program does not have access to the file.
- 该文件已被验证存在。
- 该文件经验证不存在。
- 该文件的状态未知。当程序无权访问该文件时,可能会出现此结果。
回答by Иван Белозор
i had a same problem, but your hack doesn't helped me. When file was actually exist all methods returned me false:
我有同样的问题,但你的黑客没有帮助我。当文件实际存在时,所有方法都返回 false:
Files.exists(path) = false,
path.toFile().exists() = false,
Files.notExists(path) = true,
Files.exists(path) || path.toFile().exists() = false
But if at this moment in the explorer a network directory with this file was opened, then its existence was correctly handled
但是如果此时在资源管理器中打开了包含此文件的网络目录,则正确处理了它的存在
I solved this problem by creation of a new file in directory (then delete it):
我通过在目录中创建一个新文件(然后删除它)解决了这个问题:
Files.createFile(Paths.get(path.getParent().toString(), "test"));
After that command, apparently, Windows update information about folder
在该命令之后,显然,Windows 更新了有关文件夹的信息