Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.java > #12908

Re: Files.move() scheitert, wirft aber keine Ausnahme

From Andreas Karrer <ak-6a@gmx.ch>
Newsgroups de.comp.lang.java
Subject Re: Files.move() scheitert, wirft aber keine Ausnahme
Date 2016-02-01 14:35 +0000
Message-ID <slrnnaur9p.3ko.ak-6a@chimborazo.ee.ethz.ch> (permalink)
References <dh1leaFp3b2U1@mid.individual.net>

Show all headers | View raw


* Christoph Schneegans <Christoph@Schneegans.de>:
> Hallo allerseits!
>
> In meiner Applikation gibt es folgenden Aufruf:
>
>    java.nio.Files.move(source, target,
>      java.nio.file.StandardCopyOption.REPLACE_EXISTING);
>
> Nun ist offenbar – bislang einmalig – folgendes passiert:
>
> • Die vorhandene, nicht leere Datei target wurde geleert bzw. durch eine 
> 0 Bytes großen Datei ersetzt.
> • source ist noch unverändert vorhanden (und ist nicht leer, sondern ca. 
> 1,5 MB groß).
> • Es gab _keine_ Ausnahme.
>
> Die Applikation wird unter CentOS 5.11 ausgeführt. source und target 
> sind Pfade im lokalen Dateisystem. Dieselbe Operation hat zuvor in fast 
> einer Million Fällen fehlerfrei funktioniert.

Das sollte nicht passieren können.

Files.move() geht bei Files auf einem lokalen Unix/Linux-Filesystem so vor:

  - target wird gelöscht (weil REPLACE_EXISTING)
  - rename(source, target)  (der System call rename(2))
  - wenn rename erfolgreich war, dann ist die Sache gegessen
  - EISIR (target ist ein Directory) wird irgendwie abgehandelt,
    interessiert hier nicht
  - beim Fehler EXDEV (source und target auf unterschiedlichen Filesystemen):
     - das File wird Block für Block kopiert
     - die Metainformationen (mode, owner etc) werden kopiert
     - source wird gelöscht.

Wenn source und target zwei Files auf dem gleichen lokalen Fileystem
sind, dann ist der Systemcall rename(2) unter CentOS atomar, d.h. das
beschriebene Verhalten kann nicht auftreten.

Es handelt sich im vorliegenden Fall also offenbar um Files auf
unterschiedlichen Filesystemen (oder auch dem gleichen Filesystem, das
an unterschiedlichen Mountpoints eingehängt ist). Dieser Code ist
nicht atomar, d.h. er kann (z.B. durch ein Signal, Disk voll,
Hardwarefehler oder so etwas) mittendrin unterbrochen werden. Im
beschriebenen Fall wäre das dann passiert, als das target-File bereits
zum Schreiben geöffnet war, aber noch keine Daten kopiert wurden. Das
sollte aber immer eine IOException zur Folge haben.

http://cr.openjdk.java.net/~littlee/7129029/webrev.00/src/solaris/classes/sun/nio/fs/UnixCopyFile.java.html

Es ist natürlich auch denkbar, dass der vorgefundene Zustand (source
intakt, target überschrieben und 0 Bytes gross) gar nicht durch
Files.move() ausgelöst wurde, sondern durch irgendwelchen anderen Code
in der Applikation.


 - Andi

Back to de.comp.lang.java | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Files.move() scheitert, wirft aber keine Ausnahme Christoph Schneegans <Christoph@Schneegans.de> - 2016-01-29 18:22 +0100
  Re: Files.move() scheitert, wirft aber keine Ausnahme Bastian Blank <usenet@waldi.eu.org> - 2016-01-30 10:44 +0000
  Re: Files.move() scheitert, wirft aber keine Ausnahme Bernd Laengerich <Bernd.Laengerich@web.de> - 2016-02-01 09:30 +0100
  Re: Files.move() scheitert, wirft aber keine Ausnahme Andreas Karrer <ak-6a@gmx.ch> - 2016-02-01 14:35 +0000
    Re: Files.move() scheitert, wirft aber keine Ausnahme Christoph Schneegans <Christoph@Schneegans.de> - 2016-02-02 17:55 +0100

csiph-web