簡體   English   中英

檢查文件是否已經打開

[英]Check if file is already open

我需要編寫一個自定義批處理文件重命名器。 我已經完成了大部分工作,只是我不知道如何檢查文件是否已經打開。 我只是在使用java.io.File包,並且有一個canWrite()方法,但這似乎沒有測試該文件是否正在被另一個程序使用。 關於如何使這項工作有任何想法?

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

(問答是關於如何處理 Windows“打開文件”鎖......而不是如何可移植地實現這種鎖定。)

這整個問題充滿了可移植性問題和競爭條件:

  • 您可以嘗試使用 FileLock,但您的操作系統和/或文件系統不一定支持它。
  • 在 Windows 上,如果另一個應用程序以特定方式打開文件,您可能無法使用 FileLock。
  • 即使您確實設法使用了FileLock或其他東西,您仍然會遇到問題,即在您測試文件和重命名之間可能會出現某些東西並打開文件。

一個更簡單但不可移植的解決方案是嘗試重命名(或您嘗試執行的任何操作)並診斷返回值和/或由於打開的文件而出現的任何 Java 異常。

筆記:

  1. 如果您使用Files API 而不是File API,您將在發生故障時獲得更多信息。

  2. 在允許重命名鎖定或打開文件的系統(例如 Linux)上,您不會得到任何失敗結果或異常。 手術只會成功。 但是,在此類系統上,您通常無需擔心文件是否已打開,因為操作系統不會在打開時鎖定文件。

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

在 Windows 上我找到了答案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");
}

我認為您永遠不會為此獲得明確的解決方案,操作系統不一定會告訴您文件是否打開。

您可能會從java.nio.channels.FileLock獲得一些java.nio.channels.FileLock ,盡管 javadoc 加載了警告。

嗨,我真的希望這會有所幫助。

我之前嘗試了所有選項,但沒有一個真正適用於 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

 }

如果文件正在使用FileOutputStream fileOutputStream = new FileOutputStream(file); 返回 java.io.FileNotFoundException 異常消息中的“進程無法訪問該文件,因為它正被另一個進程使用”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM