Java 检查文件是否已打开

Java 检查文件是否已打开,java,file-io,Java,File Io,我需要编写一个自定义批处理文件重命名器。我已经完成了大部分工作,只是我不知道如何检查文件是否已经打开。我只是在使用java.io.File包,有一个canWrite()方法,但它似乎无法测试该文件是否被其他程序使用。有什么办法可以让它工作吗?我不认为你会得到一个明确的解决方案,操作系统不一定会告诉你文件是否打开 您可能会从java.nio.channels.FileLock中获得一些好处,尽管javadoc中有很多注意事项。(问答是关于如何处理Windows“打开文件”锁…而不是如何可移植地实现

我需要编写一个自定义批处理文件重命名器。我已经完成了大部分工作,只是我不知道如何检查文件是否已经打开。我只是在使用
java.io.File
包,有一个
canWrite()
方法,但它似乎无法测试该文件是否被其他程序使用。有什么办法可以让它工作吗?

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

您可能会从
java.nio.channels.FileLock
中获得一些好处,尽管javadoc中有很多注意事项。

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

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

  • 您可以尝试使用FileLock,但您的操作系统和/或文件系统不一定支持它
  • 在Windows上,如果其他应用程序以特定方式打开文件,则可能无法使用FileLock
  • 即使您确实设法使用了
    FileLock
    或其他方法,您仍然会遇到这样的问题,即在测试文件和执行重命名之间,可能会出现一些问题并打开文件
一个简单但不可移植的解决方案是,只需尝试重命名(或您尝试执行的任何操作),并诊断返回值和/或由于打开文件而出现的任何Java异常

注:

  • 如果使用
    文件
    API而不是
    文件
    API,则在发生故障时将获得更多信息

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


  • 正在使用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
    }
    

    如果文件正在使用
    FileOutputStream FileOutputStream=newfileoutputstream(文件)返回java.io.FileNotFoundException,并在异常消息中显示“该进程无法访问该文件,因为它正被另一进程使用”。

    在Windows上,我使用

    fileIsLocked=!文件。重命名为(文件)


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

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

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

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

    嗨,我真的希望这有帮助

    我以前尝试过所有选项,但没有一个在Windows上真正起作用。帮助我完成这项任务的唯一想法是尝试移动文件。事件在原子移动下移动到同一位置。如果文件是由另一个程序或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
    
     }
    


    这取决于平台。这是什么平台?只是重新标记你的问题,因为你可能必须使用JNI或JNA调用WinAPI。可能的话,但我们不要急着说即使你知道它是开放的,也会有竞争条件来处理它。是的,不能保证底层操作系统,甚至文件系统,以任何合理的方式支持文件锁定。这不会对.xls文件引发任何类型的异常,只会很好地触及它。竞争条件警报!这将更改文件的最后修改日期和时间。简直是天才+1.不适用于Linux。在POSIX文件系统中,文件名不是主键,而是指向文件内容的链接。因此,您可以重命名或删除打开的文件。没有人收到任何错误。请确认此操作适用于Windows10。似乎比挑起一个例外要优雅得多。不适用于带ext4的linux。如果文件未被使用,请说明DownVotesOverwrite文件内容的原因,以便基本上删除该文件,我将不胜感激。适用于linux(ext4)和Win10。第三个否决票是我的。当我使用FileOutputStream FileOutputStream=new FileOutputStream(文件)时,我有一个例外。对正常控制流使用例外被认为是一个糟糕的做法。此外,在不生成异常的情况下,您可能会让
    fw
    处于打开状态;请尝试{String filePath=“C:\sheet.xlsx”;fw=new FileWriter(filePath);}catch(IOException e){System.out.println(“文件已打开”);}最后{fw.close();}谢谢。这是最有效和正确的答案。
     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
    
     }