2011-08-30 12 views
21

Ho circa 500 file di testo all'interno di una directory con lo stesso prefisso nel loro nome file dire dailyReport_.Elimina file con lo stesso prefisso stringa utilizzando Java

L'ultima parte del file è la data del file. (Per esempio. dailyReport_08262011.txt, dailyReport_08232011.txt)

voglio cancellare questi file utilizzando una procedura di Java (potrei andare per uno script di shell e aggiungerlo un lavoro nel crontab ma l'applicazione è destinata a utilizzato da laici).

posso cancellare un singolo file utilizzando qualcosa di simile

 try{ 
      File f=new File("dailyReport_08232011.txt"); 
      f.delete(); 
     } 
     catch(Exception e){ 
       System.out.println(e); 
     } 

ma posso cancellare i file con un certo prefisso (ad es: dailyReport08 per l'8 ° mese) ho potuto facilmente farlo in script di shell utilizzando rm -rf dailyReport08*.txt.

Ma File f=new File("dailyReport_08*.txt"); non funziona in Java (come previsto).

Ora è possibile qualcosa di simile in Java senza eseguire un ciclo che cerca nella directory i file?

Posso ottenere questo utilizzando alcuni caratteri speciali simili a * utilizzati nello script di shell?

+3

Cosa non va con loop? – user802421

+0

mi sento anche lo stesso ... perché non loop? – amod

+0

So che è possibile con loop ... ma come ho detto potrei avere un numero elevato di file (500 è solo un numero) ... quindi invece di usare un ciclo se è possibile viceversa come uno script di shell Sento che sarebbe meglio ... –

risposta

30

No, non puoi. Java è un linguaggio piuttosto di basso livello, confrontato con lo script di shell, quindi cose come questa devono essere eseguite in modo più esplicito. È necessario cercare i file con la maschera richiesta con folder.listFiles (FilenameFilter) e scorrere l'array restituito eliminando ogni voce. In questo modo:

final File folder = ... 
final File[] files = folder.listFiles(new FilenameFilter() { 
    @Override 
    public boolean accept(final File dir, 
          final String name) { 
     return name.matches("dailyReport_08.*\\.txt"); 
    } 
}); 
for (final File file : files) { 
    if (!file.delete()) { 
     System.err.println("Can't remove " + file.getAbsolutePath()); 
    } 
} 
+0

Hai ottenuto un risultato più veloce con 'FilenameFilter' che eseguire un ciclo .... Grazie –

+0

Pollice su! No per ciclo a tutti. – user802421

+0

@ user802421: C'è un ciclo for ma, intendevo evitare un loop per la ricerca di file con pattern ... e come ho detto questo dà un risultato più veloce a una logica che ho provato con un loop alla ricerca di file e cancellando quando ne ho trovato uno .... –

3

Non esiste un carattere jolly ma è possibile implementare uno FilenameFilter e controllare il percorso con uno startsWith("dailyReport_"). Quindi chiamare File.listFiles(filter) fornisce una serie di file che è possibile eseguire il ciclo e chiamare delete() su.

23

È possibile utilizzare un ciclo

for (File f : directory.listFiles()) { 
    if (f.getName().startsWith("dailyReport_")) { 
     f.delete(); 
    } 
} 
0

Non è possibile farlo senza un ciclo. Ma puoi migliorare questo ciclo. Prima di tutto, poniti una domanda: "qual è il problema con la ricerca e la rimozione nel ciclo?" Se per qualche motivo è troppo lento, puoi semplicemente eseguire il ciclo in un thread separato, in modo che non influenzi l'interfaccia utente.

Altri consigli: inserisci i rapporti giornalieri in una cartella separata e potrai rimuovere questa cartella con tutto il contenuto.

+0

Una cartella mensile accettata !!! .... potrebbe essere andato per una cartella mensile ma poi alcuni requisiti come l'unione di file (di diversi mesi) potrebbero diventare noiosi .... E il ciclo come già detto di grandi dimensioni di file ... –

2

Usa FileFilter in questo modo:

File dir = new File(<path to dir>); 
File[] toBeDeleted = dir.listFiles(new FileFilter() { 
    boolean accept(File pathname) { 
    return (pathname.getName().startsWith("dailyReport_08") && pathname.getName().endsWith(".txt")); 
    } 

for (File f : toBeDeleted) { 
    f.delete(); 
} 
+0

Questo codice eliminerebbe qualsiasi cosa (inclusi i file non 'txt') a partire da ** dailyReport_08 ** probabilmente avrebbe anche controllato anche l'estensione ... ma il codice fornito con BegemoT fornisce il risultato perfetto ... grazie in qualsiasi modo –

0

Date un'occhiata al Apache FileUtils che offre molte manipolazioni di file a portata di mano.

0

Sono d'accordo con BegemoT.

Tuttavia, una sola ottimizzazione: Se è necessario un semplice FilenameFilter, esiste una classe nei pacchetti di Google. Quindi, in questo caso non è nemmeno necessario creare la propria classe anonima.

import com.google.common.io.PatternFilenameFilter; 

final File folder = ... 
final File[] files = folder.listFiles(new PatternFilenameFilter("dailyReport_08.*\\.txt")); 

// loop through the files 
for (final File file : files) { 
    if (!file.delete()) { 
     System.err.println("Can't remove " + file.getAbsolutePath()); 
    } 
} 

Divertiti!

5

con Java 8:

public static boolean deleteFilesForPathByPrefix(final String path, final String prefix) { 
    boolean success = true; 
    try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(Paths.get(path), prefix + "*")) { 
     for (final Path newDirectoryStreamItem : newDirectoryStream) { 
      Files.delete(newDirectoryStreamItem); 
     } 
    } catch (final Exception e) { 
     success = false; 
     e.printStackTrace(); 
    } 
    return success; 
} 

Versione semplice:

public static void deleteFilesForPathByPrefix(final Path path, final String prefix) { 
    try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(path, prefix + "*")) { 
     for (final Path newDirectoryStreamItem : newDirectoryStream) { 
      Files.delete(newDirectoryStreamItem); 
     } 
    } catch (final Exception e) { // empty 
    } 
} 

modificare l'argomento percorso/String come necessario. Puoi persino convertire tra File e Percorso. Il percorso è preferito per Java> = 8.

+0

Questo è tutto effettivamente disponibile a partire da Java 7. – wrestang

2

So che sono in ritardo per la festa. Tuttavia, per riferimento futuro, volevo contribuire con una soluzione java 8 stram che non implicasse un ciclo.

Potrebbe non essere carino. Do il benvenuto a suggerimenti per farlo sembrare migliore. Tuttavia, fa il lavoro:

Files.list(deleteDirectory).filter(p -> p.toString().contains("dailyReport_08")).forEach((p) -> { 
    try { 
     Files.deleteIfExists(p); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}); 

In alternativa, è possibile utilizzare Files.walk che attraversano la directory in profondità. Cioè, se i file sono sepolti in diverse directory.

+1

Non penso che questa soluzione eviti un loop, utilizza solo la più recente sintassi. –

0
new java.io.File(<<pathStr>>).listFiles.filter(_.getName.endsWith(".txt")).foreach(_.delete()) 
0

Java 8:

final File downloadDirectory = new File("directoryPath"); 
    final File[] files = downloadDirectory.listFiles((dir,name) -> name.matches("dailyReport_.*?")); 
    Arrays.asList(files).stream().forEach(File::delete) 
Problemi correlati