Mit Locking Dateien sperren

Damit eine Datei gegen konkurrierenden parallelen Zugriff geschützt ist, lässt sie sich über Locking absichern. Um einen Lock für Dateien zu erwerben bietet die Java-API ein FileLock-Objekt. So ein FileLock bekommt ein Programm von der Methode lock() eines FileChannels – ein FileChannel wiederum kommt von getChannel(), einer Methode, die FileInputStream, FileOutputStream oder RandomAccessFile anbieten.

Beispiel: Öffne eine Datei, erzeuge exklusiven Zugriff, und schreibe Daten:

FileOutputStream fos = new FileOutputStream( file );

try ( FileLock fileLock = fos.getChannel().tryLock() ) {

  fos.write( … );

}

Hinweis: Die übliche Schreibweise OutputStream fos funktioniert natürlich nicht, da ein allgemeiner OutputStream keine getChannel()-Methode bietet.

Die lock(…)-Methode liefert als Ergebnis ein FileLock-Objekt. Das wiederum bietet einige Methoden, wobei für uns nur release() bzw. close() interessant sind, die den Lock wieder freigeben. FileLock implementiert die Schnittstelle AutoCloseable, sodass ein FileLock auch auch try-mit-Ressourcen verwendet werden kann, wie im Beispiel geschehen.

Um zu testen, ob eine gegebene Datei gelockt ist, lässt sich tryLock() verwenden – etwa mit der folgenden statischen Hilfsmethode:

public static boolean isLocked( String filename ) {

  try ( RandomAccessFile raf = new RandomAccessFile( filename, "rw" ); FileLock lock = raf.getChannel().tryLock() ) {

    // Nothing to do here

  }

  catch ( IOException e ) {

    return false;

  }

  return true;

}

Die Methoden tryLock(…) und lock(…) liefern FileLock-Objekt und diese Ressource muss immer korrekt geschlossen werden.

Hinweis: Unter Unix-Systemen gibt es kein eindeutig vorgeschriebenes Verfahren zum File-Locking[1], sodass Oracle das Sperren bisher nur so umsetzt, dass zwei Java-Programme sich gegenseitig nicht in die Quere kommen, es aber sein kann, dass ein anderes Unix-Programm diesen Lock nicht respektiert. So kann unter Unix eine Datei von mehreren Seiten gelesen werden, selbst wenn ein Java-Programm sie aktuell beschreibt. Auch kann eine Datei auf dem Dateisystem gelöscht werden, selbst wenn das Java-Programm sie noch offen hält. Das Windows-Betriebssystem unterstützt hingegen Locks. Wenn ein Prozess keinen Lock auf die Datei besitzt, kann der Prozess die Datei auch nicht lesen.


[1] Zum Beispiel mit dem Alleskönner fcntl() aus dem POSIX-Standard oder flock() von 4.2 BSD.

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.