Was macht Linux anders, damit ich Dateien entfernen / ersetzen kann, bei denen Windows sich beschwert, dass die Datei gerade verwendet wird?

29

Das Beispiel, das ich habe, ist Minecraft. Beim Ausführen von Bukkit unter Linux kann ich die .jar-Dateien im Ordner / plugins entfernen oder aktualisieren und einfach den Befehl 'reload' ausführen.

Unter Windows muss der gesamte Serverprozess heruntergefahren werden, da die JAR-Datei derzeit verwendet wird, wenn ich versuche, sie zu entfernen oder zu ersetzen.

Das ist großartig für mich, aber warum passiert das? Was macht Linux hier anders?

MetaGuru
quelle

Antworten:

34

Linux löscht eine Datei ganz anders als Windows. Zunächst eine kurze Erklärung, wie Dateien in den nativen * unix-Dateisystemen verwaltet werden.

Die Datei wird in der aufgerufenen Mehrebenenstruktur auf dem Datenträger gespeichert i-node. Jeder i-Knoten hat eine eindeutige Nummer im einzelnen Dateisystem. Die i-Node-Struktur enthält verschiedene Informationen zu einer Datei, wie z. B. ihre Größe, für die Datei zugewiesene Datenblöcke usw., aber für diese Antwort ist das wichtigste Datenelement a link counter. Dies directoriessind die Dateien, die Aufzeichnungen über die Dateien führen. Jeder Datensatz hat die i-Node-Nummer, auf die er verweist, die Dateinamenlänge und den Dateinamen selbst. Dieses Schema ermöglicht es einem, an verschiedenen Stellen mit unterschiedlichen Namen 'Zeiger', dh 'Verknüpfungen', zu derselben Datei zu haben. Der Verbindungszähler des i-Knotens speichert tatsächlich die Anzahl der Verbindungen, die auf diesen i-Knoten verweisen.

Was passiert, wenn ein Prozess die Datei öffnet? Zuerst open()sucht die Funktion nach dem Dateidatensatz. Anschließend wird geprüft, ob die speicherinterne i-Node-Struktur für diesen i-Node bereits vorhanden ist. Dies kann vorkommen, wenn in einer Anwendung diese Datei bereits geöffnet war. Andernfalls initialisiert das System eine neue speicherinterne i-Node-Struktur. Dann erhöht das System den Öffnungszähler für die speicherinterne i-Node-Struktur und gibt dessen Dateideskriptor an die Anwendung zurück.

Der Aufruf der Linux-Bibliothek zum Löschen einer Datei wird aufgerufen unlink. Diese Funktion entfernt den Dateidatensatz aus einem Verzeichnis und dekrementiert den Verbindungszähler des i-Knotens. Wenn das System feststellt, dass eine speicherinterne i-Node-Struktur vorhanden ist und der offene Zähler nicht Null ist, gibt dieser Aufruf die Steuerung an die Anwendung zurück. Andernfalls prüft es, ob der Verbindungszähler Null wurde, und wenn dies der Fall ist, gibt das System alle für den i-Knoten und den i-Knoten selbst zugewiesenen Blöcke frei und kehrt zur Anwendung zurück.

Was passiert, wenn eine Anwendung eine Datei schließt? Die Funktion close()dekrementiert den offenen Zähler und prüft seinen Wert. Wenn der Wert nicht Null ist, kehrt die Funktion zur Anwendung zurück. Andernfalls wird geprüft, ob der i-Node-Link-Zähler Null ist. Wenn es Null ist, werden alle Blöcke der Datei und des i-Nodes freigegeben, bevor zur Anwendung zurückgekehrt wird.

Mit diesem Mechanismus können Sie eine geöffnete Datei "löschen". Gleichzeitig hat die Anwendung, die eine Datei geöffnet hat, weiterhin Zugriff auf die Daten in der Datei. So behält JRE in Ihrem Beispiel weiterhin die geöffnete Dateiversion bei, während sich eine andere, aktualisierte Version auf der Festplatte befindet.

Darüber hinaus können Sie mit dieser Funktion die glibc (libc) - die Kernbibliothek aller Anwendungen - in Ihrem System aktualisieren, ohne den normalen Betrieb zu unterbrechen.

Windows

Vor 20 Jahren kannten wir unter DOS kein anderes Dateisystem als FAT. Dieses Dateisystem hat eine andere Struktur und andere Verwaltungsprinzipien. Nach diesen Grundsätzen können Sie eine Datei nicht löschen, wenn sie geöffnet wird. Daher muss Windows und DOS alle Löschanforderungen für eine geöffnete Datei ablehnen. Wahrscheinlich würde NTFS dasselbe Verhalten wie * nix-Dateisysteme zulassen, aber Microsoft hat beschlossen, das gewohnte Verhalten beim Löschen von Dateien beizubehalten.

Das ist die Antwort. Nicht kurz, aber jetzt hast du die Idee.

Bearbeiten : Eine gute Lektüre zu den Messquellen Win32: https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993 Danksagungen an @ Jon

Serge
quelle
1
Versucht, die Plugin-Datei umzubenennen,
MetaGuru
Öffne cmd Fenster, wechsle in dieses Verzeichnis und benutze ren MonsterB.jar MonsterB.ja_- es sollte funktionieren. Es funktioniert auf jeden Fall für DLL- und EXE-Dateien.
Serge
1
nein, Windows ordnet Teile der ausführbaren Datei dem Speicher zu
Serge
9
NTFS unterstützt es tatsächlich, aber der C Library- fopenBefehl ruft CreateFilemit dem FILE_SHARE_DELETEFlag auf, sodass es für die meisten Programme, die Dateien öffnen, nicht zulässig ist.
Random832
2
Obligatorischer Raymond Chen-Link: blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
Jon