2011-08-25 13 views
5

Tengo una carpeta con esta estructuraJava copiar una carpeta excluyendo algunos archivos interno

mainFolder

--Sub1 
     --File .scl 
     --File .awl 
     --Other files 
    --Sub2 
     --Files 
    --Sub3 
    --Sub4 

quiero copiar a otra ubicación, pero quiero la Sub3 que hay que evitar y (dependiendo de la situación) algún archivo de la Sub 1

he aquí un extracto de lo que hice hasta ahora:

FileUtils.copyDirectory(srcDir, dstDir, new FileFilter() { 
     public boolean accept(File pathname) { 
      // We don't want 'Sub3' folder to be imported 
      // + look at the settings to decide if some format needs to be 
      // excluded 
      String[] ignoreList= new String[]{ 
        !Settings.getSiemensOptionAWL() ? ".awl":"uselessStringWilNeverBeFound", 
        !Settings.getSiemensOptionSCL() ? ".scl":"uselessStringWilNeverBeFound", 
        "Sub3" 
      }; 

      return !(ignoreFile(pathname, ignoreList) && pathname 
        .isDirectory()); 
     } 
    }, true); 


    public static boolean ignoreFile(File file, String[] ignoreList) { 
     for (final String ignoreStr : ignoreList) 
      if (file.getAbsolutePath().contains(ignoreStr)) 
       return true; 
     return false; 
    } 

Parece que funciona. Pero creo que es una solución muy fea ... ¿Alguien sabe una mejor manera?

P.S: de Settings.getSiemensOptionAWL curso() es sólo función booleana taħt volver mi decisión

+2

Puede ser fácil copiar todo el directorio a la nueva ubicación, luego eliminar los archivos (de esa copia) que no deberían estar allí. Obviamente, esto no será apropiado si el motivo está relacionado con la seguridad en lugar de la funcionalidad básica. –

+0

Veo a qué se refiere ... pero imagínese que no tiene el riesgo de que el usuario copie los datos que no tiene el usuario.(este no es el caso, pero quiero tener una solución limpia) :) – Stefano

+0

incluso ... al parecer a veces funciona, pero en algún momento no lo hace ... tal vez hay una mejor manera de lo mismo piensa! – Stefano

Respuesta

4

Las otras opciones sugeridas son buenas, sin embargo, otra alternativa es anidar varias FileFilters más simples juntos (que puede ser una exageración, por supuesto!)

public class FailFastFileFilter implements FileFilter { 
    protected final List<FileFilter> children = new ArrayList<FileFilter>(); 

    public FailFastFileFilter(FileFilter... filters) { 
     for (FileFilter filter: filters) { 
      if (filter != null) 
       this.filters.add(filter); 
     }  
    } 

    public boolean accept(File pathname) { 
     for (FileFilter filter: this.filters) { 
      if (!filter.accept(pathname)) { 
       return false; // fail on the first reject 
      } 
     } 

     return true; 
    } 
} 

Entonces simplemente combine FileFilters cortos y concisos para el caso Sub3, el .scl y el caso .awl. El ejemplo FailFastFileFilter que he mostrado arriba le permitiría especificar null como uno de los filtros (para poder usar las sentencias If en línea para determinar si se aplican filtros de archivos en particular)

Para completarlo, le ofrecemos una idea general de cómo Implementaría los filtros secundarios para las cajas Sub1 y Sub3.

En primer lugar, un filtro para excluir archivos con una extensión en particular dentro de un directorio:

public class ExcludeExtensionInDirFileFilter implements FileFilter { 
    protected final String parentFolder; 
    protected final String extension; 

    public ExtensionFileFilter(String parentFolder, String extension) { 
     this.parentFolder = parentFolder; 
     this.extension = extension.toLowerCase(); 
    } 

    public boolean accept(File file) { 
     if (!file.isDirectory() && file.getParentFile().getName().equalsIgnoreCase(parentFolder)) 
      return !file.getAbsolutePath().toLowerCase().endsWith(extension); 
     else 
      return true; 
    } 
} 

Luego de excluir a un directorio:

public class ExcludeDirFileFilter implements FileFilter { 
    protected final String name; 

    public ExcludeDirFileFilter(String name) { 
     this.name = name.toLowerCase(); 
    } 

    public boolean accept(File file) { 
     if (file.isDirectory() && file.getName().equalsIgnoreCase(name)) 
      return false; 
     else 
      return true; 
    } 
} 

Configuración del FailFastFileFilter sería entonces algo como:

FileFilter filters = new FailFastFileFilter(
    new ExcludeDirFileFilter("Sub3"), // always exclude Sub3 
    (!Settings.getSiemensOptionAWL() ? new ExcludeExtensionInDirFileFilter("Sub1",".awl"), null), // Exclude Sub1/*.awl if desired 
    (!Settings.getSiemensOptionSCL() ? new ExcludeExtensionInDirFileFilter("Sub1",".scl"), null) // Exclude Sub1/*.scl if desired 
); 

FileUtils.copyDirectory(srcDir, dstDir, filters); 
-1

ve bastante limpio para mí. Simplemente no coloque todo eso directamente en el código de llamada para que no tenga que mirarlo todo el tiempo. Cree su propia clase CopySubDir que oculte todo este código y le proporcione una interfaz fácil de entender. Entonces el código de llamada se verá limpio.

1

¿Es el caso de los hilos fijados en piedra? Tal vez algo como

new FileFilter() { 
    public boolean accept(File pathname) { 
     String path = pathname.getAbsolutePath().toLowerCase(); 

     return (!pathname.isDirectory() || path.endsWith("sub3")) && 
      (!Settings.getSiemensOptionAWL() && path.endsWith(".awl")) && 
      (!Settings.getSiemensOptionSCL() && path.endsWith(".scl")); 
    } 
} 
+0

se ve mejor de esta manera, pero mi String no está solucionado ... depende de la configuración del software ... – Stefano

+0

acaba de salir tu código/descripción. Tal vez sea mejor utilizar el patrón decorador/cadena de responsabilidad para construir un filtro variable formado por filtros de archivo específicos de configuración más pequeños. – vickirk

+0

¡Algo parecido a la respuesta de Peter! – vickirk

3

creo que la fealdad viene de la introducción de ignoreFile(), que necesariamente se pierde parte de la información útil (que en realidad las cadenas de la materia, que son cadenas de extensiones de archivo, etc.) Además, esa matriz va a ser creado para cada archivo en su jerarquía, que es extremadamente ineficiente. Considerar algo como esto, en su lugar:

FileUtils.copyDirectory(srcDir, dstDir, new FileFilter() { 
    public boolean accept(File pathname) { 
     // We don't want 'Sub3' folder to be imported 
     // + look at the settings to decide if some format needs to be 
     // excluded 
     String name = pathname.getName(); 
     if (!Settings.getSiemensOptionAWL() && name.endsWith(".awl")) 
      return false; 
     if (!Settings.getSiemensOptionSCL() && name.endsWith(".scl")) 
      return false; 

     return !(name.equals("Sub3") && pathname.isDirectory()); 
    } 
}, true); 
+0

Esta es una solución limpia, pero creo que el primer término después de la devolución debería haber sido! Name.equals ("Sub3") en lugar de! PathName.equals ("Sub3"). –

+0

Se solucionó eso y se aclaró la parte "isDirectory()" ... –

Cuestiones relacionadas