2011-08-25 38 views
5

Tôi có một thư mục với cấu trúc nàyJava sao chép một thư mục không bao gồm một số tập tin nội bộ

mainFolder

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

Tôi muốn sao chép nó vào một vị trí khác nhưng tôi muốn các Sub3 để thể tránh được và (tùy thuộc từ tình hình) một số tập tin từ Sub1

Dưới đây là một chiết xuất từ ​​những gì tôi đã làm cho đến nay:

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

Rõ ràng là các đường nối hoạt động. Nhưng tôi nghĩ là một giải pháp rất xấu xí ... Có ai biết cách nào tốt hơn không?

Tái bút: tất nhiên Settings.getSiemensOptionAWL() chỉ là chức năng boolean taht trở quyết định của tôi

+2

Có thể dễ dàng sao chép toàn bộ thư mục sang vị trí mới, sau đó xóa các tệp (từ bản sao đó) không nên ở đó. Rõ ràng điều này sẽ không phù hợp nếu động cơ liên quan đến bảo mật hơn là chức năng cơ bản. –

+0

Tôi hiểu ý của bạn là gì ... nhưng dù sao thì không phải người dùng nào có nguy cơ sao chép dữ liệu mà bạn không có những gì người dùng có.(thi không phải là trường hợp nhưng tôi muốn có một suolution sạch) :) – Stefano

+0

thậm chí ... dường như đôi khi nó hoạt động nhưng đôi khi nó không ... có lẽ có chỉ là một cách tốt hơn để suy nghĩ tương tự! – Stefano

Trả lời

4

Các tùy chọn khác gợi ý ở đây là tốt, tuy nhiên thay thế khác là để làm tổ nhiều FileFilters đơn giản cùng nhau (có thể là quá mức cần thiết, tất nhiên!)

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

Sau đó, chỉ cần kết hợp FileFilters ngắn gọn, ngắn gọn cho trường hợp Sub3, trường hợp .scl và .awl. Ví dụ FailFastFileFilter tôi đã hiển thị ở trên sẽ cho phép bạn chỉ định null là một trong các bộ lọc (vì vậy bạn có thể sử dụng các câu lệnh nội tuyến để xác định xem các FileFilter cụ thể có được áp dụng không)

Để hoàn thành, đây là ý tưởng chung về cách thức Tôi muốn thực hiện các bộ lọc con cho các trường hợp Sub1 và trường hợp Sub3.

Thứ nhất, một bộ lọc để trừ các file có phần mở rộng cụ thể trong một thư mục:

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

Sau đó, để loại trừ một thư mục:

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

Thiết lập FailFastFileFilter sau đó sẽ giống như thế:

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

Trông khá sạch sẽ với tôi. Chỉ cần không đặt tất cả những gì trực tiếp trong mã gọi điện thoại, do đó bạn không cần phải nhìn vào nó tất cả các thời gian. Tạo lớp CopySubDir của riêng bạn để ẩn tất cả mã này và cung cấp một giao diện đơn giản để hiểu nó. Sau đó, mã gọi điện thoại sẽ trông sạch sẽ.

1

Trường hợp của chuỗi đó có được cố định bằng đá không? Có lẽ cái gì đó như

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

nó trông đẹp hơn theo cách này nhưng chuỗi của tôi không cố định ... họ phụ thuộc từ phần mềm cài đặt ... – Stefano

+0

mã/mô tả của bạn. Có lẽ bạn nên sử dụng trang trí/chuỗi mô hình trách nhiệm để xây dựng một bộ lọc biến đổi tạo thành các bộ lọc tệp nhỏ hơn, cấu hình specifc. – vickirk

+0

Một cái gì đó dọc theo dòng câu trả lời của Peter! – vickirk

3

Tôi nghĩ xấu xa xuất phát từ giới thiệu ignoreFile(), mà nhất thiết phải mất một số thông tin hữu ích (mà chuỗi thực sự vấn đề, mà chuỗi là phần mở rộng tập tin, vv) Ngoài ra, mảng đó sẽ là được tạo cho mọi tệp trong hệ thống phân cấp của bạn, điều này cực kỳ không hiệu quả. Hãy xem xét một cái gì đó như thế này, thay vì:

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

Đây là một giải pháp sạch nhưng tôi nghĩ rằng thuật ngữ đầu tiên sau khi trở về nên có được! Name.equals ("Sub3") thay vì! PathName.equals ("Sub3"). –

+0

Đã sửa lỗi và làm rõ phần "isDirectory()" ... –

Các vấn đề liên quan