【问题标题】:Is there any better way to do filefilter for many ext?有没有更好的方法来为许多分机做文件过滤?
【发布时间】:2010-10-26 06:56:49
【问题描述】:
File files[] = rootDir.listFiles(new FileFilter() {
    public boolean accept(File file) {
        if (file.isDirectory())
            return true;

    String name = file.getName().toLowerCase();

    if (name.endsWith(".zip") || name.endsWith(".jar")
     || name.endsWith(".z") || name.endsWith(".gz")
     || name.endsWith(".tar") || name.endsWith(".bz2")
     || name.endsWith(".bz"))
        return true;

    return false;
    }
});

如你所见,代码用“||”很脏

你知道如何让它变得更好吗?

【问题讨论】:

    标签: java string file-io filter


    【解决方案1】:

    对于 Java 6 或更高版本,这是 FileNameExtensionFilter 的完美案例...除了它扩展 javax.swing.filechooser.FileFilter 而不是实现 java.io.FileFilter。
    但是为它写一个包装器是微不足道的:

    File[] files = rootDir.listFiles(new FileFilter() {
        private final FileNameExtensionFilter filter =
            new FileNameExtensionFilter("Compressed files",
                "zip", "jar", "z", "gz", "tar", "bz2", "bz");
        public boolean accept(File file) {
            return filter.accept(file);
        }
    });
    

    【讨论】:

    • 扩展名(.zip、.jar、...)应该不带点。示例:new FileNameExtensionFilter("Compressed files", "zip, "jar",...)
    【解决方案2】:

    这是我的方法。 java.lang.Collections 真的是一个不错的类!而且因为我们在 HashSet 中查找给定的文件扩展名,所以它的性能更高。虽然我怀疑,但在这种情况下,这种性能真的很重要......

    // ...
    
    final Set<String> archives = new HashSet<String>();
    Collections.addAll(archives, ".zip", ".jar", ".z", ".gz", ".tar",
            ".bz2", ".bz");
    
    File files[] = rootDir.listFiles(new FileFilter() {
        public boolean accept(final File file) {
            if (file.isDirectory())
                return true;
    
            final String name = file.getName().toLowerCase();
            return archives.contains(name
                    .substring(name.lastIndexOf('.')));
    
        }
    });
    
    // ...
    

    【讨论】:

      【解决方案3】:

      您可以使用静态初始化的 HashSet 执行以下操作。就个人而言,我会将允许的扩展名提取到某种配置文件中,以使其更容易更改,但您不必这样做。

      n.b. FilenameUtils 属于 Commons I/O,其中还包括一堆使此类事情变得更容易的类。看看 FileFilterUtils,它进一步简化了事情并提供了一些很好的帮助方法。

      私有静态设置 allowedExtensions = null;

      static {
          allowedExtensions = new HashSet<String>();
          allowedExtensions.add("txt");
          allowedExtensions.add("zip");
          allowedExtensions.add("jar");
          allowedExtensions.add("gz");
      }
      
      public void filter() {
          File rootDir = new File("/");
          File files[] = rootDir.listFiles(new FileFilter() {
      
              public boolean accept(File file) {
      
                  if (file.isDirectory()) return true;
      
                  String fileName = file.getName().toLowerCase();
      
                  String extension = FilenameUtils.getExtension(fileName);
                  if (StringUtils.isNotEmpty(extension)
                      && allowedExtensions.contains(extension)) {
                      return true;
                  } else {
                      return false;
                  }
              }
          });        
      }
      

      您可以在此处找到 API:

      http://commons.apache.org/io/api-release/

      【讨论】:

      • FileNameUtils.getExtension(fileName) 很方便
      【解决方案4】:

      我刚写完这门课:

      class FileExtensionFilter implements FileFilter {
      
          private final String[] validExtensions;
      
          public FileExtensionFilter(String... validExtensions) {
              this.validExtensions = validExtensions;
          }
      
          public boolean accept(File pathname) {
              if (pathname.isDirectory()) {
                  return true;
              }
      
              String name = pathname.getName().toLowerCase();
      
              for (String ext : validExtensions) {
                  if (name.endsWith(ext)) {
                      return true;
                  }
              }
      
              return false;
          }
      }
      

      用法:

      File files[] = directory.listFiles(
                        new FileExtensionFilter(".zip", ".jar", ".z", ".tar"));
      

      顺便说一句,这是一个可重用的类,你甚至可以使用装饰器模式等附加检查来包装它。

      附言

      刚刚注意到 FileNameExtensionFilter 的存在

      【讨论】:

        【解决方案5】:

        一些伪代码解决方案:

        遍历数组

        suffixes = [".tar", ".zip", ".jpg"]
        
        for suffix in suffixes:
            if name.endsWith(suffix):
                return True
        

        使用集合

        suffixes = [".tar", ".zip", ".jpg"]
        
        nameSuffix = name.getSuffix()
        if nameSuffix in suffixes:
            return True
        

        【讨论】:

          【解决方案6】:

          您可以静态创建一个映射,如果文件扩展名是映射中的一个键,则返回 true。

          或者您可以尝试将文件名与正则表达式进行匹配(但我会选择使用映射)。

          【讨论】:

            【解决方案7】:

            为什么不使用正则表达式?

            static final Pattern p = Pattern.compile("\\.(zip|jar|z|gz)$");

            然后return p.matcher(name).find();

            【讨论】:

            • 或者更简单,使用带有 String#matches 的正则表达式,例如 name.matches(".*?\\.(zip|jar|z|gz)$")。
            • 文件系统遍历是利用预编译模式提高性能的少数几个地方之一。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-21
            • 2021-08-11
            • 1970-01-01
            相关资源
            最近更新 更多