2009-02-18 15 views
27

Supponendo di avere un File f che rappresenta una directory, quindi f.delete() eliminerà la directory solo se è vuota. Ho trovato uno couple di examples online che utilizza File.listFiles() o File.list() per ottenere tutti i file nella directory e poi attraversa in modo ricorsivo la struttura di directory ed elimina tutti i file. Tuttavia, poiché è possibile creare strutture di directory infinitamente ricorsive (sia in Windows sia in Linux (con collegamenti simbolici)) presumibilmente è possibile che i programmi scritti con questo stile non possano mai terminare.Eliminazione di directory non vuote in Java

Quindi, c'è un modo migliore per scrivere un programma di questo tipo in modo che non cada in queste insidie? Devo tenere traccia di tutto ciò che ho attraversato e assicurarmi di non girare in tondo o c'è un modo più bello?

Aggiornamento: In risposta ad alcune delle risposte (grazie ragazzi!) - Preferirei che il codice non seguisse collegamenti simbolici e rimase nella directory che avrebbe dovuto eliminare. Posso fare affidamento sull'implementazione Commons-IO per farlo, anche nel caso di Windows?

risposta

32

Se si desidera veramente che l'eliminazione della directory ricorsiva segua tramite collegamenti simbolici, non penso che ci sia alcun modo indipendente dalla piattaforma per farlo senza tenere traccia di tutte le directory che si sono attraversate.

Tuttavia, in quasi tutti i casi, posso pensare di voler semplicemente eliminare il collegamento simbolico effettivo che punta alla directory anziché ricorsivamente seguendo il collegamento simbolico.

Se questo è il comportamento desiderato, è possibile utilizzare il metodo FileUtils.deleteDirectory in Apache Commons IO.

3

File.getCanonicalPath() ti dirà il nome "reale" del file, inclusi i collegamenti simbolici risolti. Quando durante la scansione ti imbatti in una directory che conosci (perché li hai archiviati in un bacheca di tipo Map).

+0

Avrei pensato che avrebbe rallentato una cancellazione ricorsiva un po '. Non potresti fare un file.getPath(). Equals (File.getCanonicalPath())? –

+0

Non sono sicuro di quanti miliardi di directory ricorsive si desidera elaborare, ma Map.put() e Map.contains() per directory non rallenteranno. Il codice che hai suggerito ti direbbe solo che da qualche parte nel tuo percorso ci sono collegamenti simbolici. Potrebbero essere sopra la directory che si desidera eliminare. – Bombe

+2

Onestamente: preoccuparsi di ottenere il lavoro prima.Solo se funziona perfettamente e puoi misurare che è _too_ slow (qualunque cosa ciò significhi), solo allora inizierai a preoccuparti delle prestazioni. L'ottimizzazione prematura è così senza cervello che mi fa male. Fisicamente. – Bombe

0

Se si è a conoscenza di quali file sono collegamenti simbolici, è possibile ignorarli.

Purtroppo non esiste un modo "pulito" per rilevare i collegamenti simbolici in Java. Scopri this soluzione alternativa Java o this one che coinvolge codice nativo.

7

Provare Apache Commons IO per un'implementazione testata.

Tuttavia, non penso che questo gestisca il problema di infinito-ricorsione.

+2

guarda la fonte: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?view=markup Vedrai il deleteDirectory non segue i collegamenti simbolici. – elou

0

Almeno in MacOSX, l'eliminazione di un collegamento simbolico a una directory non elimina la directory stessa e può quindi essere eliminata anche se la directory di destinazione non è vuota.

Presumo che ciò valga per la maggior parte dei sistemi operativi POSIX. E per quanto ne so, i collegamenti in Windows sono anche solo file e possono essere cancellati come tali da un programma Java.

Problemi correlati