检查文件是否已经打开
我需要写一个自定义的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。
笔记:
-
如果您使用
Files
API而不是File
API,您将在发生故障时获得更多信息。 -
在允许您重命名(或其他)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与'进程无法访问该文件,因为它正被另一个进程使用'。