Temp-Datei wird nicht gelöscht

Hallo Forum,

gibt es hierfür eine elegante Lösung? Ich lege beim Programmstart eine temporäre Datei an, welche via RandomAccessFile permanent geöffnet bleibt, um bestimmte Lese- und Schreiboperationen vorzunehmen.

Wie eigentlich schon zu erwarten war, wird die Datei trotz .deleteOnExit() nicht gelöscht, weil die Datei zum Zeitpunkt des Schließens wohl noch geöffnet ist.

protected void finalize() {
myRandomAccessFile.close();
}


... bringt's schon mal leider nicht...
 
Vielleicht sollte ich noch dazu sagen, dass sich das Ganze in einer abgekapselten Bibliothek abspielt, das eigentliche Programm "weiß" also sozusagen nichts von der temporären Datei. Die Bibliothek sollte sich also eigenständig drum kümmern. Ein manueller wie auch immer gearteter Aufruf von .close() aus dem Programm heraus gebietet sich also eher nicht so... ;-)
 
"Was machst du denn bitte genau?"

In der Datei werden Undo/Redo-Aktionen gespeichert, die zu "speicherintensiv" sind, als dass man sie im RAM ablegen könnte/sollte.

Ja, war eben auch mein Verdacht, dass finalize() nicht aufgerufen wird. Ist im Prinzip auch logisch, denn wozu die ganzen Finalisierer aufrufen, wenn die VM gerade dabei ist sich komplett zu beenden.
 
Vielleicht sollte ich noch dazu sagen, dass sich das Ganze in einer abgekapselten Bibliothek abspielt, das eigentliche Programm "weiß" also sozusagen nichts von der temporären Datei. Die Bibliothek sollte sich also eigenständig drum kümmern. Ein manueller wie auch immer gearteter Aufruf von .close() aus dem Programm heraus gebietet sich also eher nicht so... ;-)
Also meiner Meinung nach sollten dann Instanzen, die sowas haben, eben auch Closeable / AutoCloseable implementieren, damit die Verwender mitbekommen, dass da eine Ressource geöffnet wird, die geschlossen werden muss wenn man fertig ist.

Und dann ist das eine einfache Close Methode, die das Schließen des temporären Files halt mit veranlasst.
 
Danke für Deine Antwort! AutoClosable gibt's leider erst ab Java 7, ich arbeite noch mit 6. Daher fällt diese Variante leider schon mal weg.

Letztendlich wird's wohl darauf hinauslaufen (müssen), dass ich die Datei bei Zugriff immer wieder neu öffne und anschließend wieder schließe. Nicht 100%ig befriedigend, aber besser so, als die Datei gar nicht zu löschen und damit auf Dauer unnötig den Festplattenplatz vollzumüllen.
 
Danke für Deine Antwort! AutoClosable gibt's leider erst ab Java 7, ich arbeite noch mit 6. Daher fällt diese Variante leider schon mal weg.
Aber Closeable sollte es doch auch schon vorher gegeben haben? Ist schon so lange her, dass ich mich nicht erinnere....
Ansonsten einfach ohne Interface ein close() anbieten und in der Doku entsprechend beschreibe...

Letztendlich wird's wohl darauf hinauslaufen (müssen), dass ich die Datei bei Zugriff immer wieder neu öffne und anschließend wieder schließe. Nicht 100%ig befriedigend, aber besser so, als die Datei gar nicht zu löschen und damit auf Dauer unnötig den Festplattenplatz vollzumüllen.
Da bin ich jetzt nicht sicher, ob und wie das Dein Problem löst (Was aber natürlich auch nicht wichtig ist. Wenn Du eine Lösung hast, mit der Du arbeiten kannst, dann ist es super. Mir muss das auch nicht erläutert werden, aber ich bin halt ein neugieriger Mensch :) ): Geschlossen wird die Datei ja. So Inhalte fehlen, dann wäre ein regelmäßiges flushen evtl. zielführend. So wie ich dich verstanden hatte, ist ja das Problem, dass die Datei beim Schließen der Applikation nicht gelöscht wird.

Oder meinst Du damit, dass z.B. mit Speichern der Datei der undo Speicher gelöscht wird, d.h. beim Speichern wird die Datei geschlossen und damit gelöscht? (Das würde dann natürlich funktionieren und wäre eine Lösung für das Problem aber halt auf Kosten der Undo-Funktionalität).

Eine andere Idee könnte evtl. sein, dass die Datei(en) geöffnet bleiben und bei Programmstart ein "cleanup" durchgeführt wird. (Das wäre das, was man z.B. von Tools wie notepad++ kennt. Ich liebe es für Notizen auf Arbeit: Einfach neues Tab und reinschreiben. Wird nie gespeichert und ist bei jedem Neustart halt direkt wieder da... Sprich: So ein cleanup kann ja beliebig definiert werden: Verwendung der Dateien soweit möglich oder einfaches löschen von alten, nicht mehr verwendeten Dateien..)

Das wären einfach nur meine Gedanken dazu. Keine Ahnung, ob sie hilfreich für Dich sind, denn ich bin mir sicher, dass du das Alles und noch mehr bestimmt schon in der Tiefe alles durchdacht hast.
 
>> Da bin ich jetzt nicht sicher, ob und wie das Dein Problem löst

Na ja, weil nach jedem Zugriff auf die Datei jedes Mal ein Aufruf von RandomAccessFile#close() folgt, ist die Datei eben nicht mehr geöffnet, wenn das Programm vom Anwender geschlossen wird, folglich wird die Datei von der VM gemäß .deleteOnClose() "ordnungsgemäß" gelöscht. Das wäre eben dann die Lösung.

>> Eine andere Idee könnte evtl. sein, dass die Datei(en) geöffnet bleiben und bei Programmstart ein "cleanup" durchgeführt wird.

Das ist übrigens auf jeden Fall eine gute Variante, komisch, dass ich nicht von selbst drauf gekommen bin. Danke!

Damit habe ich schon mal 2 Alternativen. Damit kann ich arbeiten. ;-)
 
>> Da bin ich jetzt nicht sicher, ob und wie das Dein Problem löst

Na ja, weil nach jedem Zugriff auf die Datei jedes Mal ein Aufruf von RandomAccessFile#close() folgt, ist die Datei eben nicht mehr geöffnet, wenn das Programm vom Anwender geschlossen wird, folglich wird die Datei von der VM gemäß .deleteOnClose() "ordnungsgemäß" gelöscht. Das wäre eben dann die Lösung.
Mein Verständnis ist, dass bei der StandardOpenOption.DELETE_ON_CLOSE die Detei beim schließen der Datei gelöscht wird und nicht beim schließen der VM.
Somit wäre die Datei nach deinem RandomAccessFile#close() Aufruf nicht nur nicht mehr geöffnet sondern auch direkt gelöscht.

Aber ich möchte nicht ausschließen, dass ich irgendwas missverstanden habe und Du ein anderes deleteOnClose verwendest als das, was ich gerade vor Augen habe (Zumal ich bei allen Recherchen zu Lösungen immer Java 7+ sehe - also da kann es dann auch noch Unterschiede geben!). Zur Not gilt: Einfach einmal testen und schauen ob es funktioniert. Hier würde ich mich für Dich freuen, wenn ich einfach falsch liegen würde. :)
 
Ich würde auch versuchen, das Interface des ganzen um Closeable zu erweitern, wäre mMn die sauberste Lösung.

Ansonsten könnte man uU mit Shutdown-Hooks arbeiten, und dort den Stream schließen und die Datei selbst löschen.

Kann natürlich trotzdem beim Start noch vorhanden sein, sollte also dort in jedem Fall geleert werden. Eine Möglichkeit wären da aber temporäre Dateien, dann hat man jeden Start ne neue (oder wenn mehrere Instanzen laufen)
 
Runtime.getRuntime().addShutdownHook(new Thread() { public void run() {
try { if (randomAccessFile != null) randomAccessFile.close(); } catch (Exception e) {}
}});


<-- funktioniert anstandslos. Danke für den Tipp!

Ich meinte übrigens vorher File#deleteOnExit(), nicht ~OnClose, letztere Methode gibt es gar nicht. Und die erfüllt nun einwandfrei ihre Funktion, nachdem die geöffnete Datei via Shutdown-Hook geschlossen wurde.

Mit Closeable/AutoCloseable bin ich bislang nicht in Berührung gekommen, muss ich zugeben. Wenn ich es richtig verstehe, ruft die VM nur im Falle von AutoCloseable close() automatisch beim Beenden auf? Implementiere ich jedenfalls Closeable und schreibe obigen Code in die close()-Methode, so bewirkt das nichts.
 
Mit Closeable/AutoCloseable bin ich bislang nicht in Berührung gekommen, muss ich zugeben. Wenn ich es richtig verstehe, ruft die VM nur im Falle von AutoCloseable close() automatisch beim Beenden auf? Implementiere ich jedenfalls Closeable und schreibe obigen Code in die close()-Methode, so bewirkt das nichts.
Nein, die VM ruft nichts automatisch auf.

Close ist einfach nur ein Interface, dass besagt, dass es eine Methode close() gibt. Das ist für Nutzer der Klasse dann nur der Hinweis: Hey, wenn Du mich verwendest, dann bitte sei doch so nett und rufe einmal "close()" auf, wenn Du fertig bist.

AutoCloseable ist erst zusammen mit dem "try with resources" gekommen. Bei dem try with resources handelt es sich um ein konstrukt, welches das automatische Schließen mit einbezieht. Also ein
Java:
try (SomeAutoCloseableClass variableName = .... ) {
  // Some Code
}
entspricht ungefähr einem
Java:
{
  SomeAutoCloseableClass variableName;
  try {
      variableName = ....;
    // Some Code
  } finally {
      if (variableName != null) variableName.close();
  }
}
Ansonsten super, dass Du eine funktionierende Lösung gefunden hast und diese mit uns geteilt hast.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben