2011-08-25 14 views
5

Ho una cartella con questa strutturaJava copiare una cartella escludendo alcuni file interno

mainFolder

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

voglio copiare in un'altra posizione ma voglio la SUB3 da evitare e (a seconda da la situazione) alcuni file dal Sub1

Ecco un estratto da quello che ho fatto finora:

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

Apparentemente sembra funzionare. Ma penso sia una soluzione molto brutta ... Qualcuno sa un modo migliore?

P.S: ovviamente Settings.getSiemensOptionAWL() è solo funzione booleana Taht tornare la mia decisione

+2

Potrebbe essere facile copiare l'intera directory nella nuova posizione, quindi eliminare i file (da quella copia) che non dovrebbero essere lì. Ovviamente questo non sarà appropriato se il motivo è legato alla sicurezza piuttosto che alla funzionalità di base. –

+0

Capisco cosa intendi ... ma non puoi immaginare che cosa l'utente ha il rischio di copiare i dati che non è ciò che l'utente deve avere.(non è il caso, ma voglio avere una soluzione pulita) :) – Stefano

+0

anche ... a volte a volte funziona, ma a volte no ... forse c'è solo un modo migliore per lo stesso pensa! – Stefano

risposta

4

Le altre opzioni suggerite qui sono buone, però un'altra alternativa è quella di nidificare più FileFilters più semplici insieme (che può essere eccessivo, ovviamente!)

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

Poi basta combinare FileFilters brevi e concisi per il caso Sub3, il caso .scl e il caso .awl. L'esempio FailFastFileFilter che ho mostrato sopra ti permetterebbe di specificare null come uno dei filtri (quindi potresti usare le istruzioni inline if per determinare se sono applicati FileFilters specifici)

Per motivi di completezza, ecco un'idea generale di come Implementerei i filtri figlio per i casi Sub1 e il caso Sub3.

In primo luogo, un filtro per escludere i file con un'estensione particolare all'interno di una directory:

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

Poi per escludere una directory:

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

Impostazione del FailFastFileFilter sarebbe poi un aspetto simile:

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

sembra piuttosto pulito per me. Basta non mettere tutto ciò direttamente nel codice chiamante in modo da non doverlo guardare tutto il tempo. Crea la tua classe CopySubDir che nasconde tutto questo codice e fornisce un'interfaccia semplice da comprendere. Quindi il codice chiamante apparirà pulito.

1

E 'il caso di quelle corde fisse in pietra? Forse qualcosa di simile

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

sembra più bello in questo modo ma la mia stringa non è fissa ... essi dipendono dalle impostazioni del software ... – Stefano

+0

appena usciti il tuo codice/descrizione Forse sei tu a usare il pattern decoratore/catena di responsabilità per costruire un filtro variabile composto da filtri di file specifc più piccoli e config. – vickirk

+0

Qualcosa sulla falsariga della risposta di Peter! – vickirk

3

Penso che la bruttezza viene da introdurre ignoreFile(), che perde necessariamente alcune delle informazioni utili (che le stringhe in realtà la materia, che le stringhe sono le estensioni dei file, ecc) Inoltre, tale matrice sta per essere creato per ogni file nella tua gerarchia, che è estremamente inefficiente. Considerare qualcosa come questo, invece:

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

Questa è una soluzione pulita ma penso che il primo termine dopo il ritorno avrebbe dovuto essere! Name.equals ("Sub3") invece di! PathName.equals ("Sub3"). –

+0

Risolto il problema e chiarito la parte "isDirectory()" ... –

Problemi correlati