Überprüfen Sie, ob die Datei bereits geöffnet ist

Ich muss einen benutzerdefinierten Batch-Datei-Renamer schreiben. Ich habe den Großteil davon erledigt, außer dass ich nicht herausfinden kann, wie man überprüft, ob eine Datei bereits geöffnet ist. Ich benutze nur das java.io.File Paket und es gibt eine canWrite() -Methode, aber diese scheint nicht zu testen, wenn die Datei von einem anderen Programm verwendet wird. Irgendwelche Ideen, wie ich das schaffen kann?

Solutions Collecting From Web of "Überprüfen Sie, ob die Datei bereits geöffnet ist"

Verwenden der Apache Commons IO-Bibliothek …

 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 } 

(Im Q & A geht es darum, wie man mit Windows-Dateisperren umgehen kann … nicht, wie man diese Art von Sperren portabel implementiert.)

Dieses ganze Problem ist mit Portabilitätsproblemen und Rassenkonditionen behaftet:

  • Sie könnten versuchen, FileLock zu verwenden, aber es wird nicht unbedingt für Ihr Betriebssystem und / oder Dateisystem unterstützt.
  • Es scheint, dass Sie unter Windows möglicherweise FileLock nicht verwenden können, wenn eine andere Anwendung die Datei auf eine bestimmte Weise geöffnet hat.
  • Selbst wenn Sie es geschafft haben, FileLock oder etwas anderes zu verwenden, haben Sie immer noch das Problem, dass etwas dazwischenkommt und die Datei zwischen dem Testen der Datei und dem Umbenennen öffnet.

Eine einfachere und (wahrscheinlich) robustere Lösung besteht darin, einfach die Umbenennung (oder was auch immer Sie gerade versuchen) zu versuchen und den Rückgabewert und / oder alle Java-Ausnahmen zu diagnostizieren, die aufgrund geöffneter Dateien auftreten.

Anmerkungen:

  1. Wenn Sie die File API anstelle der File API verwenden, erhalten Sie im Falle eines Fehlers mehr Informationen.

  2. Auf Systemen, auf denen Sie eine gesperrte oder offene Datei umbenennen dürfen (oder was auch immer), erhalten Sie keine Fehler oder Ausnahmen. Die Operation wird nur erfolgreich sein.

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

org.apache.commons.io.FileUtils.touch(yourFile) überprüft nicht, ob Ihre Datei geöffnet ist oder nicht. Stattdessen wird der Zeitstempel der Datei in die aktuelle Zeit geändert.

Ich habe IOException verwendet und es funktioniert gut:

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

Ich glaube nicht, dass Sie jemals eine endgültige Lösung dafür bekommen werden, das Betriebssystem wird Ihnen nicht unbedingt sagen, ob die Datei geöffnet ist oder nicht.

Aus java.nio.channels.FileLock können Sie möglicherweise einen gewissen Kilometerverbrauch java.nio.channels.FileLock , obwohl das java.nio.channels.FileLock mit Vorbehalten geladen ist.

Unter Windows fand ich die Antwort https://stackoverflow.com/a/13706972/3014879 mit

fileIsLocked = !file.renameTo(file)

am nützlichsten, da es False Positives bei der Verarbeitung schreibgeschützter Dateien vermeidet.

Wenn die Datei verwendet wird FileOutputStream fileOutputStream = new FileOutputStream(file); Gibt java.io.FileNotFoundException mit ‘Der process kann nicht auf die Datei zugreifen, da sie von einem anderen process verwendet wird’ in der Ausnahmebedingungsnachricht zurück.