PDA

View Full Version : Probleme beim Löschen von Dateien



Seiten : [1] 2

KM
11-09-08, 10:04
Hallo,

mein Problem gehört jetzt zwar nicht direkt in die Kategorie Java auf iSeries, aber vielleicht kann mir trotzdem jemand helfen.

Ich habe derzeit massive Probleme beim Löschen von Dateien. Ich habe z.B. folgenden Java-Code, der auf einem Windows-Server unter Java 1.6 läuft:


// Dateien einzeln runterladen
FileOutputStream fos = new FileOutputStream(new File(localfile));
c.get(remotefile, fos); // --> FTP-Übertragung
fos.close();
fos = null;
System.gc();
.
.
.
File f = new File(localfile);
f.delete();


Der Teil, der durch die Punkte dargestellt ist, ist für alle Dateien gleich.
Wenn ich die Routine mit mehreren Dateien durchlaufe, werden nur manche sporadisch gelöscht und manche bleiben stehen. Es sollen eigentlich alle gelöscht werden.

Jetzt habe ich schon mehrfach gelesen, dass man vor dem delete() unbedingt den Garbage Collector anschubsen soll, weil es sonst Probleme geben könnte. Auf der anderen Seite habe ich aber auch gelesen, dass der System.gc() eigentlich nie verwendet werden soll. Ich dachte eigentlich, dass mit obigem Code die Referenzen auf die localfile komplett gelöscht werden, so dass der delete eigentlich funktionieren müsste. Das scheint aber nicht so zu sein.

Wie kann ich denn sonst noch sicherstellen, dass eine Datei auch wirklich gelöscht wird ?

Danke,
KM

Fuerchau
11-09-08, 10:12
Ich denke, indem du sie nicht verwendest.
Es muss doch andere Befehle geben, die eine Datei löschen ohne sie erst mal zu öffnen.

Für den GC musst du ggf. deinen Thread mal ein bisschen pausieren, damit der gc auch Zeit bekommt.

Andererseits müsste der f.delete() einen Fehler auslösen, dass das z.Zt. nicht geht.
Bekommst du keinen Fehler, kommst du im Code an der Datei nicht vorbei.

BenderD
11-09-08, 10:56
soweit man das in diesem Ausschnitt sehen kann, sieht das nach works as designed aus. Dein f.delete() wird von Windows ausgeführt, das wohl Einwände wg. Benutzung hat (die durchaus von noch nicht vom gc abgeholten Objekten kommen könnten), in solchen Fällen kommt dann halt false zurück. Der Aufruf von System.gc() kommt zurück, wenn die Runtime meint, dass sie jetzt genug aufgeräumt hat, ansonsten ist der gc eh' nebenläufig in einem eigenen Thread.
Ich denke das kriegt man nur im Design weg, notfalls ein Pool von temporären Objekten/Dateien und einem eigenen Aufräumthread, wobei ich erst nochmal ein wenig über die zu Grunde liegende Anforderung nachdenken würde!

mfg

Dieter Bender

Hallo,

mein Problem gehört jetzt zwar nicht direkt in die Kategorie Java auf iSeries, aber vielleicht kann mir trotzdem jemand helfen.

Ich habe derzeit massive Probleme beim Löschen von Dateien. Ich habe z.B. folgenden Java-Code, der auf einem Windows-Server unter Java 1.6 läuft:


// Dateien einzeln runterladen
FileOutputStream fos = new FileOutputStream(new File(localfile));
c.get(remotefile, fos); // --> FTP-Übertragung
fos.close();
fos = null;
System.gc();
.
.
.
File f = new File(localfile);
f.delete();


Der Teil, der durch die Punkte dargestellt ist, ist für alle Dateien gleich.
Wenn ich die Routine mit mehreren Dateien durchlaufe, werden nur manche sporadisch gelöscht und manche bleiben stehen. Es sollen eigentlich alle gelöscht werden.

Jetzt habe ich schon mehrfach gelesen, dass man vor dem delete() unbedingt den Garbage Collector anschubsen soll, weil es sonst Probleme geben könnte. Auf der anderen Seite habe ich aber auch gelesen, dass der System.gc() eigentlich nie verwendet werden soll. Ich dachte eigentlich, dass mit obigem Code die Referenzen auf die localfile komplett gelöscht werden, so dass der delete eigentlich funktionieren müsste. Das scheint aber nicht so zu sein.

Wie kann ich denn sonst noch sicherstellen, dass eine Datei auch wirklich gelöscht wird ?

Danke,
KM

KM
11-09-08, 14:29
Das heißt ich muß dann wohl eine Schleife programmieren, in der ich immer wieder versuche die Datei zu löschen, bis es endlich funktioniert hat.

Und dabei geht es doch nur um so eine banale Sache wie das Löschen einer Datei...

Gruß,
KM

Fuerchau
11-09-08, 14:42
Eigentlich sollte der Close die Datei wieder freigeben.
Ggf. hast du aber noch ein anderes Objekt, dass die Datei noch geöffnet hält ?

RobertPic
11-09-08, 17:20
Wenn die Files keinen weiteren Einfluss auf die Programmlogik haben, könntest du es mit:

deleteOnExit() probieren, der merkt sich die Datei bis zum Ende VM und löscht sie dann.

eventuell auch.
if (!file.delete()) {
file.deleteOnExit();
}

Hier die API (http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#deleteOnExit%28%29)

/Robert

KM
11-09-08, 17:34
Hallo Robert,

den deleteOnExit hab ich auch schon gesehen. Aber wie Du schon sagst löschen der die Datei erst beim Beenden der JVM. Und da das Programm in einem Tomcat läuft, würde das ewig warten, weil dieser nur einmal am Tag neu gestartet wird.

Ich werd's wohl doch mal mit einer Schleife versuchen. Bleibt mir wohl nix anderes übrig.

Trotzdem Danke,
KM

RobertPic
11-09-08, 18:03
Noch eine andere Frage:
Wo wird den die Datei verarbeitet?

Ich nehme an, dass c.get den FTP Transfer mach. Irgendwo muss das File ja ja auch verarbeitet (InputStream) werden. Dort könnte es ja auch Referenzen geben.

/Robert
.

KM
11-09-08, 18:22
Ja, der c.get macht den FTP-Transfer. Bei dieser Datei handelt es sich um eine XML-Datei, die nach der Übertragung einfach nur validiert wird und dann wieder gelöscht wird.

Jetzt hab ich mal direkt nach der Validierung in einem finally-Block eingebaut, dass die Referenzen sämtlicher verwendeter Objekte explizit auf null gesetzt werden. Und danach führe ich noch einen System.gc() durch. Mal sehen was ich jetzt für ein Ergebnis erhalte. Wenn das Problem dann immernoch besteht, kann es eigentlich nur noch ein Zeitproblem sein, weil der GC dann offenbar nicht schnell genug greift.

Gruß,
KM

Fuerchau
12-09-08, 09:33
Wie gesagt, der gc dürfte gar nicht das Problem sein, da dieser nur aufräumt (vergessene Close auch schließt).

Ein expliziter Close muss die Ressource Datei freigeben!

Vielleicht gibts ja eine Ausnahme, die dein Programm nicht zum Close der Datei führt, so dass eben der Delete fehlschlägt.