检查文件是否已经打开

我需要写一个自定义的batch file重命名。 我已经完成了大部分工作,除非我无法弄清楚如何检查文件是否已经打开。 我只是使用java.io.File包,并有一个canWrite()方法,但似乎并没有testing该文件是否正在被另一个程序使用。 关于如何使这项工作的任何想法?

使用Apache Commons IO库…

 boolean isFileUnlocked = false; try { org.apache.commons.io.FileUtils.touch(yourFile); isFileUnlocked = true; } catch (IOException e) { isFileUnlocked = false; } if(isFileUnlocked){ // Do stuff you need to do with a file that is NOT locked. } else { // Do stuff you need to do with a file that IS locked } 

(Q&A是关于如何处理Windows“打开文件”的锁…并不是如何实现这种locking的。)

这整个问题充满了可移植性问题和竞争条件:

  • 您可以尝试使用FileLock,但不一定支持您的操作系统和/或文件系统。
  • 看来在Windows上,如果另一个应用程序以特定方式打开文件,则可能无法使用FileLock。
  • 即使你设法使用FileLock或其他东西,你仍然有问题,可能会进来,并在testing文件和重命名之间打开文件。

一个更简单的(可能)更强大的解决scheme是尝试重命名(或者你正在尝试做的任何事情),并诊断返回值和/或由于打开的文件引起的任何Javaexception。

笔记:

  1. 如果您使用Files API而不是File API,您将在发生故障时获得更多信息。

  2. 在允许您重命名(或其他)locking或打开的文件的系统上,您不会得到任何失败结果或exception。 操作就会成功。

你最好的办法是在文件上设置一个独占锁。 如果文件被其他进程打开,你将会得到一个exception。 例如,

 File file = new File(fileName); FileChannel channel = new RandomAccessFile(file, "rw").getChannel(); // Get an exclusive lock on the whole file FileLock lock = channel.lock(); try { lock = channel.tryLock(); // Ok. You get the lock } catch (OverlappingFileLockException e) { // File is open by someone else } finally { lock.release(); } 
  // TO CHECK WHETHER A FILE IS OPENED // OR NOT (not for .txt files) // the file we want to check String fileName = "C:\\Text.xlsx"; File file = new File(fileName); // try to rename the file with the same name File sameFileName = new File(fileName); if(file.renameTo(sameFileName)){ // if the file is renamed System.out.println("file is closed"); }else{ // if the file didnt accept the renaming operation System.out.println("file is opened"); } 

我不认为你会得到一个明确的解决scheme,操作系统不一定会告诉你,如果文件是否打开。

你可能会从java.nio.channels.FileLock获得一些里程,尽pipejavadoc已经加载了警告。

在Windows上,我find了答案https://stackoverflow.com/a/13706972/3014879使用;

fileIsLocked = !file.renameTo(file)

最有用的,因为它避免了处理写保护文件时的误报。

org.apache.commons.io.FileUtils.touch(yourFile)不检查你的文件是否打开。 而是将文件的时间戳更改为当前时间。

我用IOException,它工作得很好:

 try { String filePath = "C:\sheet.xlsx"; FileWriter fw = new FileWriter(filePath ); } catch (IOException e) { System.out.println("File is open"); } 

如果文件正在使用FileOutputStream fileOutputStream = new FileOutputStream(file); 在exception消息中返回java.io.FileNotFoundException与'进程无法访问该文件,因为它正被另一个进程使用'。