【问题标题】:Java - check safely if a file exist on a network driveJava - 安全检查网络驱动器上是否存在文件
【发布时间】:2015-04-01 11:24:41
【问题描述】:

我想测试一个文件是否存在于已挂载的网络驱动器上。

我使用File.exists 编写了这个简单的代码。

import java.io.File;

public class NetworkDrive {
    public static void main(String[] args) {
        System.err.println(new File("/Volumes/DATA/testedFile.txt").exists());
    }
}

它大部分情况下都能正常工作,但我发现此代码存在问题的边缘情况。 如果驱动器已安装并且由于某种原因网络连接失败, 程序挂起很长时间(10 分钟)。

time java NetworkDrive
false

real    10m6.114s
user    0m0.431s
sys 0m0.949s

即使我尝试使用KILL 信号杀死它,进程仍在运行。

1875 ttys000    0:00.00 (java)

问题和java.nio一样:

Files.exists(Paths.get("/Volumes/DATA/testedFile.txt"));

我在 OS X Yosemite 上使用 java 版本 1.8.0_20。

【问题讨论】:

  • 虽然应该不会有太大变化,但是你试过java.nio.file.Files#exists()吗?
  • @fge,是的。这是我第一次尝试。
  • 那么,坚持 java.nio.file。这是 2015 年,无论如何你都应该放弃 File
  • 我很抱歉,但两者都失败了。我有完全相同的问题:Files.exists(Paths.get("/Volumes/DATA/testedFile.txt"))
  • 是的,我明白,这不是我的意思;我的意思是,如果您使用 java.nio.file,请删除文件使用情况。文件有很多 java.nio.file 没有的问题。

标签: java macos filesystems


【解决方案1】:

Java 中的 File#exists 方法只是对原生 O/S 调用的封装,而这正是需要很长时间的原因。我的建议是在您的程序中实现超时;假设如果调用在较短的时间内没有返回,则该文件不存在。 Simple timeout in java 指出了一种可能的方式。

编辑:即使使用 KILL 信号也无法终止线程这一事实表明系统调用是不可中断的。这是 O/S 的问题,Java 无法解决。虽然它确实会阻止程序在调用运行时结束(即使您将线程标记为守护进程),但您仍然可以通过在另一个线程中执行调用来解决它:这样,您可以假设调用在之后失败即使调用仍在后台运行,主线程中的超时时间也会更短并继续执行程序。

【讨论】:

  • 是的,我尝试在另一个线程中运行此代码,但超时。它工作......主要是。但是例如,线程没有响应,所以我无法退出应用程序。
  • @DavidZimmerman 指的是守护线程,它不会阻止 JVM 退出。您可以通过将 stackoverflow.com/q/7158587/1980909 中定义的 ThreadFactory 作为第二个参数传递给简单超时示例中的 Executors#newScheduledThreadPool 调用来做到这一点。
  • @AdrianLeonhard 我也尝试过使用守护线程。线程根本没有响应,使我的应用程序保持活动状态。
  • 如果您无法从操作系统中终止线程/进程(如果我理解正确,这就是您尝试使用 KILL 信号执行的操作),这可能意味着文件系统调用是不可中断的...如果是这种情况,则无法使用 Java 解决问题。如果其他应用程序尝试访问有问题的网络驱动器,它们会停止响应吗?
  • @AdrianLeonhard 哦,很好发现!我对一个简单的tail -f /Volumes/DATA/testedFile.txt 也有同样的问题。您能否更新您的答案,我会接受!谢谢,即使我的问题没有解决……至少诊断更好。
【解决方案2】:

File 类严重依赖本地文件系统,但并不知道它背后有某种网络。 如果您想让应用程序保持响应,您可以尝试从另一个Thread 调用new File("/Volumes/DATA/testedFile.txt").exists()

希望这会有所帮助。

【讨论】:

  • 这是我尝试过的。它工作......主要是。但是例如后台线程没有响应,所以我无法退出应用程序。
  • 您可以通过使线程成为守护线程 (setDaemon(true)) 来解决此问题
猜你喜欢
  • 1970-01-01
  • 2017-09-09
  • 2011-04-21
  • 2015-01-30
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多