2011-08-30 18 views
21

Tengo alrededor de 500 archivos de texto dentro de un directorio con el mismo prefijo en su nombre de archivo, por ejemplo dailyReport_.Eliminar archivos con la misma cadena de prefijo usando Java

La última parte del archivo es la fecha del archivo. (Por ej. dailyReport_08262011.txt, dailyReport_08232011.txt)

quiero eliminar estos archivos mediante un procedimiento de Java (podría ir para un script de shell y añadirlo un trabajo en el crontab pero la aplicación está destinada a utilizado por los legos).

puedo borrar un solo archivo usando algo como esto

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

pero puedo borrar los archivos que tienen un determinado prefijo (por ejemplo: dailyReport08 para el mes octavo) que fácilmente podría hacer que en shell script mediante el uso de rm -rf dailyReport08*.txt.

Pero File f=new File("dailyReport_08*.txt"); no funciona en Java (como se esperaba).

Ahora, ¿es posible tal cosa en Java sin ejecutar un bucle que busca archivos en el directorio?

¿Se puede lograr esto usando algunos caracteres especiales similares a * utilizados en el script de shell?

+3

Lo malo en bucle? – user802421

+0

también siento lo mismo ... ¿por qué no loop? – amod

+0

Sé que es posible con el bucle ... pero como he dicho, podría tener una gran cantidad de archivos (500 es solo un número) ... así que en lugar de usar un bucle, si es posible, al revés, como un script de shell Siento que sería mejor ... –

Respuesta

30

No, no se puede. Java es un lenguaje de bajo nivel, en comparación con el script de shell, por lo que debe hacerse de forma más explícita. Debe buscar los archivos con la máscara requerida con folder.listFiles (FilenameFilter), e iterar a través de la matriz devuelta eliminando cada entrada. De esta manera:

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

Obtuve un resultado más rápido con 'FilenameFilter' que ejecutando un ciclo .... Gracias –

+0

¡Pulgar arriba! No para bucle en absoluto. – user802421

+0

@ user802421: Hay un bucle for, pero tenía la intención de evitar un bucle para buscar archivos con patrón ... y como dije, esto da un resultado más rápido a una lógica que probé con un bucle buscando archivos y borrando cuando encontré uno .... –

3

No hay un comodín pero puede implementar un FilenameFilter y verificar la ruta con un startsWith("dailyReport_"). Luego, al llamar al File.listFiles(filter), obtendrá una matriz de archivos que puede recorrer y llamar a delete().

23

Usted puede utilizar un bucle

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

No se puede hacer sin un bucle. Pero puedes mejorar este ciclo. En primer lugar, le hago una pregunta: "¿cuál es el problema de buscar y eliminar en el ciclo?" Si es demasiado lento por alguna razón, puede ejecutar su ciclo en una secuencia separada, para que no afecte su interfaz de usuario.

Otros consejos: coloque sus informes diarios en una carpeta separada y luego podrá eliminar esta carpeta con todo el contenido.

+0

Una carpeta mensual estuvo de acuerdo !!! ... podría haber ido por una carpeta mensual, pero luego ciertos requisitos como la fusión de archivos (de diferentes meses) podrían volverse tediosos ... Y el bucle como ya se ha dicho grande no de archivos ... –

2

Uso FileFilter así:

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

Este código eliminaría cualquier cosa (incluidos los archivos 'txt') comenzando con ** dailyReport_08 ** probablemente también habría verificado la extensión también ... pero el código dado BegemoT da el resultado perfecto. Gracias. de cualquier manera –

0

Para consultar todas Apache FileUtils que ofrece muchas manipulaciones de archivos a mano.

0

Estoy de acuerdo con BegemoT.

Sin embargo, solo una optimización: Si necesita un simple FilenameFilter, hay una clase en los paquetes de Google. Entonces, en este caso, ni siquiera tiene que crear su propia clase anónima.

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()); 
    } 
} 

Enjoy!

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; 
} 

Versión sencilla:

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 
    } 
} 

Modificar el argumento de ruta/Cadena según sea necesario. Incluso puede convertir entre Archivo y Ruta. La ruta es preferida para Java> = 8.

+0

Todo esto está realmente disponible a partir de Java 7. – wrestang

2

Sé que llego tarde a la fiesta. Sin embargo, para referencia futura, quería contribuir con una solución java 8 stram que no involucra un bucle.

Puede que no sea lindo. Agradezco sugerencias para que se vea mejor. Sin embargo, se hace el trabajo:

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

Como alternativa, puede utilizar Files.walk que atravesar el directorio primero en profundidad. Es decir, si los archivos están enterrados en directorios diferentes.

+1

No creo que esta solución evite un bucle, simplemente usa la sintaxis más nueva. –

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) 
Cuestiones relacionadas