Java-Dateisperren und Windows - das Schloss ist nicht „absolut“?
Frage
Ich versuche, eine Datei mit Java in Windows-Umgebung zu sperren mit FileLock und ich habe ein Problem aufgetreten: nachdem ich die Datei, um sie noch sperren können durch andere Prozesse zumindest auf einer bestimmten Ebene zugegriffen werden.
Beispiel-Code folgt:
public class SimpleLockExample {
public static void main(String[] args) throws Exception {
String filename = "loremlipsum.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
String firstLine = raf.readLine();
System.out.println("First line of file : " + firstLine);
waitForEnter();
lock.release();
} catch (OverlappingFileLockException e) {
e.printStackTrace();
}
lock.release();
System.out.println("Lock released");
channel.close();
}
private static void waitForEnter() throws Exception {
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
reader.close();
}
}
Nun, wenn ich meine Datei mit diesem Beispiel zu sperren, ist es gesperrt:
- Es kann nicht von Windows gelöscht werden
- Eclipse-weigert, es zu öffnen
... aber es ist immer noch nicht völlig kugelsicher:
- Wenn ich es mit Scite öffnen (ein Texteditor), zum Beispiel, wird kein Inhalt angezeigt, aber wenn ich wählen Sie die Datei speichern (leer als geöffnet oder mit einem gewissen Inhalt geschrieben), gelingt es, und der Inhalt der Datei ist gelöscht ... (kein Inhalt, selbst wenn ich etwas mit Scite geschrieben hatte es danach vorhanden ist)
Gibt es eine Möglichkeit, die Datei vollständig zu verhindern, daß überschrieben / gelöscht durch andere Prozesse mit Java in Windows?
Wenn ich richtig verstanden habe, ich bin mit exklusiver Sperre atm. Mit gemeinsamer Sperre gibt es noch mehr Dinge, die getan werden können.
Dieser Test mit Windows 2000 ausgeführt wurde.
br, Touko
Lösung
Tricky, die FileLock API selbst verspricht nicht viel:
Diese Datei sichernde API soll Karte direkt auf die native Verriegelungs Anlage des zugrunde liegenden Betriebs System. So sind die Sperren auf einer Datei gehalten sollte für alle Programme sichtbar sein, dass haben Zugriff auf die Datei, unabhängig davon, die Sprache, in der diese Programme geschrieben werden.
Ob eine Sperre tatsächlich verhindert ein anderes Programm aus Zugreifen auf den Inhalt des verriegelten Region ist systemabhängig und daher nicht näher bezeichnet. Der Einheimische Datei-Verriegelungseinrichtungen einiger Systeme sind lediglich beratende, was bedeutet, dass Programme müssen kooperativ beobachten, die ein bekanntes Sperrprotokoll in Um zu gewährleisten Datenintegrität. Auf andere Systeme nativen Dateisperren sind obligatorisch, dass, wenn ein Programm was bedeutet, sperrt ein Bereich einer Datei dann andere Programme verhindert tatsächlich aus diese Region in einer Weise zugreift, die würde die Sperre verletzen. Auf noch andere Systeme, ob native Dateisperren sind Beratungs oder obligatorisch ist konfigurierbar auf einer Pro-Datei-Basis. Sicherstellen konsistentes und korrektes Verhalten auf Plattformen, wird dringend empfohlen, dass die Sperren, die von dieser API zur Verfügung gestellt werden verwendet, als ob sie Beratungssperren waren.
Seltsamer, die Diskussion über das File-Locking-API, wenn es in der Entwicklung war behauptet, dass Windows-Betriebssystem zur Verfügung gestellt obligatorisch Sperren und auf Unix nur beratende Sperrungen. Also auf das Lesen eines Codes an die Arbeit erwarten könnte ganz gut unter Windows.
Ich frage mich, ob das, was es geschieht, dass Ihr Editor nicht so sehr um die Datei zu modifizieren, wie eine temporäre Datei erstellen und dann Verzeichniseinträge, um die Manipulation der Version der Datei, die Sie mit einer neuen Version gesperrt haben zu REPLCE. Würde von Windows erlauben ein solches Verhalten?
Ich frage mich, ob Sie zu JNI zurückgreifen müssen den Grad der Kontrolle, die Sie benötigen.
Andere Tipps
Ihr Anruf zu .tryLock () kann null zurück, wenn es nicht die Sperre bekommt. Von der Javadoc:
Ein Sperrobjekt repräsentiert die neu erworbene Schloss, oder null, wenn die Sperre nicht erworben werden kann, weil ein anderes Programm eine überlappende Sperre hält
Auch der Code zur Zeit die Datei öffnet und dann es versucht, eine Sperre zu erwerben. Stattdessen sollten Sie Schleife versucht, die Sperre zu bekommen, und wenn Sie es haben, öffnen Sie die Datei, lesen Sie die Datei, schließen Sie die Datei, dann die Sperre aufgeben. Und geben Sie die Sperre in einer finally {}
Klausel auf, nur für den Fall des Code eine Ausnahme mit dem Schloss wirft gehalten. (Hatten Sie schon mal einen Windows-Rechner neu zu starten, nur weil einige Datei gesperrt wurde?)