Ich habe einen Java-Prozess, der eine Datei mit einem FileReader öffnet. Wie kann ich verhindern, dass ein anderer (Java) Prozess diese Datei öffnet, oder zumindest diesen zweiten Prozess benachrichtigen, dass die Datei bereits geöffnet ist? Wird dadurch der zweite Prozess automatisch eine Ausnahme erhalten, wenn die Datei geöffnet ist (was mein Problem löst), oder muss ich sie im ersten Prozess explizit mit einer Art Flag oder Argument öffnen?
Zu klären:
Ich habe eine Java-App, die einen Ordner auflistet und jede Datei in der Liste zur Verarbeitung öffnet. Es verarbeitet jede Datei nach der anderen. Die Verarbeitung jeder Datei besteht aus dem Lesen und einigen Berechnungen basierend auf dem Inhalt. Sie dauert ca. 2 Minuten. Ich habe auch eine andere Java-App, die das Gleiche tut, aber stattdessen in die Datei schreibt. Ich möchte, dass diese Apps gleichzeitig ausgeführt werden können, damit das Szenario so aussieht. ReadApp listet den Ordner auf und findet die Dateien A, B, C. Es öffnet die Datei A und startet das Lesen. WriteApp listet den Ordner auf und findet die Dateien A, B, C. Es öffnet die Datei A, sieht, dass sie geöffnet ist (ausnahmsweise oder auf welche Weise auch immer) und wechselt zu Datei B. ReadApp beendet Datei A und fährt mit B fort. Es sieht, dass dies der Fall ist ist offen und fährt mit C fort. Es ist entscheidend, dass WriteApp dies nicht tut. t Schreiben, während ReadApp dieselbe Datei liest oder umgekehrt. Sie sind verschiedene Prozesse.
Antworten:
FileChannel.lock ist wahrscheinlich das, was Sie wollen.
(Haftungsausschluss: Code nicht kompiliert und schon gar nicht getestet.)
Beachten Sie den Abschnitt "Plattformabhängigkeiten" im API-Dokument für FileLock .
quelle
FileOutputStream
).FileOutputStream
wird für a nicht viel nützenReader
.NonWritableChannelException
, weillock()
versucht wird, eine exklusive Sperre zu erhalten, aber das erfordert Schreibzugriff. Wenn Sie einen Eingabestream haben , können Sie einen verwenden,lock(0L, Long.MAX_VALUE, false)
der eine gemeinsame Sperre erhält und nur einen Lesezugriff erfordert. Sie können auch eineRandomAccessFile
im Lese- / Schreibmodus geöffnete Funktion verwenden, wenn Sie beim Lesen eine exklusive Sperre wünschen ... dies würde jedoch gleichzeitige Leser verbieten.lock(0L, Long.MAX_VALUE, true)
, nichtlock(0L, Long.MAX_VALUE, false)
. Das letzte Argument istboolean shared
docs.oracle.com/javase/8/docs/api/java/nio/channels/…Verwenden Sie nicht die Klassen im
java.io
Paket, sondern dasjava.nio
Paket. Letzterer hat eineFileLock
Klasse. Sie können eine Sperre auf a anwendenFileChannel
.quelle
Wenn Sie Java NIO ( JDK 1.4 oder höher ) verwenden können, dann suchen Sie wahrscheinlich
java.nio.channels.FileChannel.lock()
FileChannel.lock ()
quelle
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine
Verwenden Sie java.nio.channels.FileLock in Verbindung mit java.nio.channels.FileChannel
quelle
Dies ist vielleicht nicht das, wonach Sie suchen, aber im Interesse, ein Problem aus einem anderen Blickwinkel zu lösen ...
Sind dies zwei Java-Prozesse, die möglicherweise auf dieselbe Datei in derselben Anwendung zugreifen möchten? Vielleicht können Sie den gesamten Zugriff auf die Datei einfach über eine einzige synchronisierte Methode filtern (oder, noch besser, mit JSR-166 )? Auf diese Weise können Sie den Zugriff auf die Datei steuern und möglicherweise sogar Zugriffsanforderungen in die Warteschlange stellen.
quelle
Verwenden Sie eine RandomAccessFile, rufen Sie den Kanal ab und rufen Sie lock () auf. Der von Eingabe- oder Ausgabestreams bereitgestellte Kanal verfügt nicht über ausreichende Berechtigungen, um ordnungsgemäß zu sperren. Rufen Sie im finally-Block unbedingt lock () auf (das Schließen der Datei hebt die Sperre nicht unbedingt auf).
quelle
Unten finden Sie einen Beispiel-Snippet-Code zum Sperren einer Datei, bis der Prozess von JVM ausgeführt wird.
quelle