2011-08-25 90 views
5

我有一個文件夾與此結構的Java複製文件夾排除一些內部文件

mainFolder

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

我想將它複製到另一個位置,但我想避免Sub3中和(根據來自情況)從Sub1的

這裏是一些文件是從我做了什麼至今的摘錄:

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

顯然它接縫工作。但我認爲是一個非常醜陋的解決方案.... 有沒有人知道更好的方法?

P.S:當然Settings.getSiemensOptionAWL的 ()僅僅是布爾函數taht返回我的決定

+2

將整個目錄複製到新位置可能很容易,然後刪除該文件(來自該副本)不應該在那裏。顯然,如果動機是與安全相關的而不是基本功能,則這不合適。 –

+0

我明白你是什麼意思......但是想象一下你不會有什麼用戶有複製數據的風險,你不知道用戶擁有什麼。(並非如此,但我想要一個乾淨的解決方案:) :) – Stefano

+0

甚至...顯然有時它的工作原理,但有時它不......可能只是一個更好的方式來相同的想法! – Stefano

回答

4

這裏提出的其他選項都不錯,但另一種選擇是嵌套多個簡單的文件過濾器一起(這可能是矯枉過正,當然!)

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

然後簡單地將Sub3案例,.scl和.awl案例簡短的FileFilter結合起來。我上面顯示的示例FailFastFileFilter會讓你指定null作爲過濾器之一(因此你可以使用內聯if語句來確定是否應用特定的FileFilter)

爲了完成,下面是一個總體思路我會爲Sub1例子和Sub3例子實現子過濾器。

首先,一個過濾器,與目錄內的特定擴展名排除文件:

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

然後排除目錄:

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

建立FailFastFileFilter然後會看起來像:

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

看起來很乾淨給我。只是不要把所有這些直接放在調用代碼中,所以你不必一直看。製作你自己的CopySubDir類,隱藏所有這些代碼,並提供一個簡單易懂的界面。然後調用代碼看起來很乾淨。

1

這些字符串固定在石頭上嗎?也許像

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

它看起來更好這種方式,但我的字符串不固定...他們依靠軟件設置... – Stefano

+0

剛剛關閉你的代碼/描述。也許你會用什麼來使用裝飾器/責任鏈模式來構造一個可變過濾器,它由較小的配置特定文件過濾器組成。 – vickirk

+0

彼得的答案沿線的東西! – vickirk

3

我覺得醜陋來源於引進ignoreFile(),這必然失去了一些有用的信息(這串實際的事情,這字符串是文件擴展名等)。此外,該陣列將是爲您的層次結構中的每個文件創建,這是非常低效的。考慮這樣的事情,而不是:

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

這是一個乾淨的解決方案,但我認爲返回後的第一項應該是!name.equals(「Sub3」)而不是!pathName.equals(「Sub3」)。 –

+0

修正並澄清了「isDirectory()」部分... –

相關問題