Java 检查文件是否已经打开

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1390592/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:34:34  来源:igfitidea点击:

Check if file is already open

javafile-io

提问by hello_world_infinity

I need to write a custom batch File renamer. I've got the bulk of it done except I can't figure out how to check if a file is already open. I'm just using the java.io.Filepackage and there is a canWrite()method but that doesn't seem to test if the file is in use by another program. Any ideas on how I can make this work?

我需要编写一个自定义批处理文件重命名器。我已经完成了大部分工作,只是我不知道如何检查文件是否已经打开。我只是在使用该java.io.File包,并且有一种canWrite()方法,但似乎无法测试该文件是否正在被另一个程序使用。关于如何使这项工作有任何想法?

回答by skaffman

I don't think you'll ever get a definitive solution for this, the operating system isn't necessarily going to tell you if the file is open or not.

我认为您永远不会为此获得明确的解决方案,操作系统不一定会告诉您文件是否打开。

You might get some mileage out of java.nio.channels.FileLock, although the javadoc is loaded with caveats.

java.nio.channels.FileLock尽管 javadoc 加载了警告,但您可能会从中获得一些好处。

回答by Stephen C

(The Q&A is about how to deal with Windows "open file" locks ... not how implement this kind of locking portably.)

(问答是关于如何处理 Windows“打开文件”锁......而不是如何可移植地实现这种锁定。)

This whole issue is fraught with portability issues and race conditions:

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

  • You could try to use FileLock, but it is not necessarily supported for your OS and/or filesystem.
  • It appears that on Windows you may be unable to use FileLock if another application has opened the file in a particular way.
  • Even if you did manage to use FileLockor something else, you've still got the problem that something may come in and open the file between you testing the file and doing the rename.
  • 您可以尝试使用 FileLock,但您的操作系统和/或文件系统不一定支持它。
  • 在 Windows 上,如果另一个应用程序以特定方式打开文件,您可能无法使用 FileLock。
  • 即使您确实设法使用FileLock或其他东西,您仍然会遇到问题,即在您测试文件和进行重命名之间可能会出现某些东西并打开文件。

A simpler though non-portable solution is to just try the rename (or whatever it is you are trying to do) and diagnose the return value and / or any Java exceptions that arise due to opened files.

一个更简单但不可移植的解决方案是尝试重命名(或您尝试执行的任何操作)并诊断返回值和/或由于打开的文件而出现的任何 Java 异常。

Notes:

笔记:

  1. If you use the FilesAPI instead of the FileAPI you will get more information in the event of a failure.

  2. On systems (e.g. Linux) where you are allowed to rename a locked or open file, you won't get any failure result or exceptions. The operation will just succeed. However, on such systems you generally don't need to worry if a file is already open, since the OS doesn't lock files on open.

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

  2. 在允许重命名锁定或打开文件的系统(例如 Linux)上,您不会得到任何失败结果或异常。手术只会成功。但是,在此类系统上,您通常无需担心文件是否已打开,因为操作系统不会在打开时锁定文件。

回答by JavaMachine31

Using the Apache Commons IO library...

使用 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
}

回答by Ahmed Adel Ismail

    //  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");
    }

回答by Aikerima

If file is in use FileOutputStream fileOutputStream = new FileOutputStream(file);returns java.io.FileNotFoundException with 'The process cannot access the file because it is being used by another process' in the exception message.

如果文件FileOutputStream fileOutputStream = new FileOutputStream(file);正在使用中,则在异常消息中返回 java.io.FileNotFoundException 并带有“进程无法访问该文件,因为它正被另一个进程使用”。

回答by siddhartino

On Windows I found the answer https://stackoverflow.com/a/13706972/3014879using

在 Windows 上我找到了答案https://stackoverflow.com/a/13706972/3014879使用

fileIsLocked = !file.renameTo(file)

fileIsLocked = !file.renameTo(file)

most useful, as it avoids false positives when processing write protected (or readonly) files.

最有用,因为它可以在处理写保护(或只读)文件时避免误报。

回答by Ali

org.apache.commons.io.FileUtils.touch(yourFile)doesn't check if your file is open or not. Instead, it changes the timestamp of the file to the current time.

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

I used IOException and it works just fine:

我使用了 IOException 并且它工作得很好:

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

回答by Dan Ortega

Hi I really hope this helps.

嗨,我真的希望这会有所帮助。

I tried all the options before and none really work on Windows. The only think that helped me accomplish this was trying to move the file. Event to the same place under an ATOMIC_MOVE. If the file is being written by another program or Java thread, this definitely will produce an Exception.

我之前尝试了所有选项,但没有一个真正适用于 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

 }