java-检查文件是否已经打开
我需要编写一个自定义的批处理文件重命名器。 我已经完成了大部分工作,但我不知道如何检查文件是否已打开。 我只是使用java.io.File程序包,并且有canWrite()方法,但这似乎无法测试文件是否正在被另一个程序使用。 关于如何进行这项工作的任何想法?
8个解决方案
23 votes
使用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
}
JavaMachine31 answered 2020-02-08T07:53:24Z
13 votes
(问与答是关于如何处理Windows“打开文件”锁的问题,而不是便携式移植这种锁的方法。)
这整个问题充满了可移植性问题和竞赛条件:
您可以尝试使用FileLock,但是您的操作系统和/或文件系统不一定支持它。
似乎在Windows上,如果另一个应用程序以特定方式打开了文件,则可能无法使用FileLock。
即使您确实设法使用了Files或其他功能,您仍然遇到问题,即在您测试文件和进行重命名之间可能会打开文件并打开文件。
一个更简单但不可移植的解决方案是仅尝试重命名(或尝试执行的任何操作)并诊断返回值和/或由于打开的文件而引起的任何Java异常。
笔记:
如果使用Files API而不是File API,则在发生故障时会获得更多信息。
在允许您重命名锁定或打开的文件的系统(例如Linux)上,不会收到任何失败结果或异常。 该操作将成功。 但是,在此类系统上,您通常不必担心文件是否已打开,因为操作系统不会在打开时锁定文件。
Stephen C answered 2020-02-08T07:54:21Z
9 votes
// 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");
}
Ahmed Adel Ismail answered 2020-02-08T07:54:36Z
5 votes
在Windows上,我使用以下命令找到了答案[https://stackoverflow.com/a/13706972/3014879]
fileIsLocked = !file.renameTo(file)
最有用,因为它在处理写保护(或只读)文件时避免了误报。
siddhartino answered 2020-02-08T07:55:05Z
3 votes
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");
}
Ali answered 2020-02-08T07:55:29Z
1 votes
我认为您不会为此找到任何确定的解决方案,操作系统不一定会告诉您文件是否打开。
尽管Javadoc加载了警告,但您可能会从java.nio.channels.FileLock中获得一些收益。
skaffman answered 2020-02-08T07:55:54Z
0 votes
嗨,我真的希望这会有所帮助。
我之前尝试过所有选项,但在Windows上都无法正常使用。 帮助我完成此任务的唯一想法是尝试移动文件。 事件发生在ATOMIC_MOVE下的同一地点。 如果文件是由另一个程序或Java线程编写的,则肯定会产生异常。
try{
Files.move(Paths.get(currentFile.getPath()),
Paths.get(currentFile.getPath()), StandardCopyOption.ATOMIC_MOVE);
// DO YOUR STUFF HERE SINCE IT IS NOT BEING WRITTEN BY ANOTHER PROGRAM
} catch (Exception e){
// DO NOT WRITE THEN SINCE THE FILE IS BEING WRITTEN BY ANOTHER PROGRAM
}
Dan Ortega answered 2020-02-08T07:56:19Z
-4 votes
如果文件正在使用中FileOutputStream fileOutputStream = new FileOutputStream(file);返回java.io.FileNotFoundException,并且在异常消息中显示“该进程无法访问该文件,因为该文件正在被另一个进程使用”。
Aikerima answered 2020-02-08T07:56:41Z