Domanda

Ciao, sto usando molti file temporanei in Java e il mio problema è che non vengono eliminati.

Senza dover implementare la mia gestione della gestione temporanea dei file (non è difficile, ti concedo, ma sono pigro più con così tante cose da fare Se riesco a salvare reinventando la ruota per tutto questo) c'è un modo per garantire i file temporanei su disco verranno eliminati in modo abbastanza regolare.

1 - usando File tmp = File.createTempFile (), sono sicuro di poter dire tmp.deleteOnExit () ma se l'oggetto viene eseguito in un servizio l'unico modo in cui esce è quando si arresta in modo anomalo (accade raramente) o quando il il sistema si arresta in modo anomalo (come quando l'unità è completamente piena di file temporanei e fa cadere il cluster ... oops!)

Idealmente, le istanze create vengono raccolte ad un certo punto dal Garbage Collector e, dato che c'è un MOLTO tempo di inattività nell'applicazione, sarebbe semplicemente dandy se il GC potesse, beh, finire la sua pulizia ed effettivamente cancellare anche il file su disco quando si dereferenzia l'istanza dalla memoria.

l'unico modo che vedo per ora è sovraccaricare la classe File e aggiungere un metodo finalizzato ... Se lo faccio, potrebbe anche andare con il mio gestore di file temporanei!

Per farla breve, posso usare Garbage Collector per ripulire anche le risorse di sistema (ovvero i file)?


Grazie a tutti per le risposte. Ho accettato Christoffer perché era il più semplice da implementare ed è quello che ho finito per fare.

Immagino che essere stato ripulito dopo così tanti anni mi abbia fatto dimenticare le pulizie di base che avrei dovuto fare nel modo più duro nei bei giorni del C ++.

È stato utile?

Soluzione

Sicuro che puoi. La domanda è se vuoi davvero :)

In realtà ho riscontrato questo problema in natura; come hai notato, ripulire i file temporanei con deleteOnExit () è inutile quando si esegue un servizio anziché un'applicazione. Ho scoperto che la soluzione più stabile era quella di ristrutturare il flusso del programma in modo tale che i file temporanei fossero creati in base alle singole attività e cancellati esplicitamente quando non erano più necessari.

Se lo fai diversamente, ovvero se il programma non è in grado di stabilire se un file temporaneo debba essere conservato o scartato in qualsiasi momento durante l'esecuzione, potresti avere un problema di progettazione. L'avvolgimento dei file in alcuni cablaggi del gestore rimanderebbe semplicemente il & Quot; real & Quot; soluzione;)

Altri suggerimenti

Potresti voler esaminare PhantomReference :

  

Gli oggetti di riferimento fantasma, che vengono accodati dopo che il raccoglitore determina che i loro referenti potrebbero altrimenti essere recuperati. I riferimenti fantasma vengono spesso utilizzati per pianificare le azioni di pulizia pre-mortem in un modo più flessibile di quanto sia possibile con il meccanismo di finalizzazione Java.

Fare affidamento su un evento per sparare quando la tua classe viene distrutta non sarà infallibile e potrebbe lasciare indietro i file.

Penso che il modo più semplice e affidabile per ottenere la pulizia dei tuoi file temporanei sia il seguente:

  • Scrivi un gestore di eventi per quando il tuo programma si chiude per ripulire tutti i file che hai aperto durante la sessione corrente.
  • Scrivi una procedura che verrà eseguita all'avvio del programma, che elimina tutti i file temporanei in questa cartella che sono più vecchi di 24 ore.

Con questo approccio non devi temere se il tuo programma si arresta in modo anomalo per qualche motivo e lascia indietro i file temporanei e non devi preoccuparti del programma che elimina i file che sono ancora in uso.

Garbage Collection è lo spazio dei nomi errato per questo tipo di gestione delle informazioni.

Il seguente punto dovrebbe essere sufficiente per gestire i file temporanei.

  1. Dovresti provare a cancellare il file direttamente dopo che non lo usi più. Un blocco finalizza può gestirlo.

  2. DeleteOnExit che dovresti usare.

  3. È possibile creare i file temporanei in una directory temporanea speciale. Questa directory temporanea è possibile eliminare all'avvio e alla chiusura dell'applicazione, per essere sicuri che non siano presenti file temporanei dopo la chiusura dell'applicazione.

Il Garbage Collector non è utile per queste cose. È progettato per la gestione della memoria e può avere molti aspetti negativi.

  • Il tuo oggetto potrebbe essere raccolto molto tempo dopo che il file non è più in uso.
  • Il tuo oggetto non è garantito per essere raccolto affatto.

Entrambe le cose accadono soprattutto spesso, se Java viene avviato con una grande dimensione heap - una cosa che sul lato server non è inusuale.

Ad un certo punto del tuo programma devi chiudere gli Stream su quel file (altrimenti mangeresti handle di file di sistema, il che rende il sistema inutilizzabile, l'ho già fatto). Nel momento in cui chiudi i flussi, puoi anche eliminare il file associato. Questo è il modo più pulito.

Bene, potresti creare un wrapper per un file che utilizza un finalizzatore per eliminare il tuo file quando l'oggetto viene spazzato via.

Ma i finalizzatori non vengono chiamati in modo prevedibile, quindi non lo consiglierei affatto.

Garbage Collector non è un posto dove liberare questo tipo di risorse. Consulta questi due articoli di seguito su come liberare risorse in Java http://c2.com/cgi/wiki?ReleasingResourcesInJava E anche i problemi di prestazioni con i finalizzatori Java. Possono fornire alcune informazioni e comprensione su come dovrebbe essere usato. http://www.enyo.de/fw/notes/java- gc-finalizers.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top