2015-10-05 103 views
1

我嘗試從classpath(web-inf/classes/dir)獲取文件列表。getResources()僅返回枚舉1個對象

Enumeration<URL> en = getClass().getClassLoader().getResources("dir"); 

但是,而不是此文件夾中的元素,唯一的元素是文件夾本身。有沒有一種方法可以獲取文件列表,或者唯一的方法是逐個訪問文件。因爲當我嘗試引用同一文件夾中的某個文件時,我可以輕鬆訪問其內容。

+0

這是正確的,你應該從枚舉中獲得'URL',構造一個「'File'」。然後調用'file.listFiles();' –

回答

1

您無法以遞歸方式瀏覽類路徑上的目錄。

看到這個職位:How to use ClassLoader.getResources() correctly?

如果你知道無論你正在尋找一個JAR文件,可以直接打開它作爲存檔和瀏覽文件。

有人想出了這個問題的一個有用的答案:Get all of the Classes in the Classpath

你可以適應這個代碼在所有JAR文件和目錄在classpath中瀏覽和應用一些過濾器爲您的目錄名稱自己。這個例子將列出所有類從gnu.trove *包:

import java.io.File; 
import java.util.Enumeration; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 

public class Test 
{ 

    public static void main(String[] args) 
    { 
     final String dirname = "gnu.trove."; 

     findClasses(new Visitor<String>() { 

      @Override 
      public boolean visit(String classname) 
      { 
       if (classname.startsWith(dirname)) { 
        System.out.println(classname); 
       } 
       return true; 
      } 
     }); 
    } 

    public interface Visitor<T> 
    { 
     public boolean visit(T t); 
    } 

    public static void findClasses(Visitor<String> visitor) 
    { 
     String classpath = System.getProperty("java.class.path"); 
     String[] paths = classpath.split(System.getProperty("path.separator")); 

     String javaHome = System.getProperty("java.home"); 
     File file = new File(javaHome + File.separator + "lib"); 
     if (file.exists()) { 
      findClasses(file, file, true, visitor); 
     } 

     for (String path : paths) { 
      file = new File(path); 
      if (file.exists()) { 
       findClasses(file, file, true, visitor); 
      } 
     } 
    } 

    private static boolean findClasses(File root, File file, 
      boolean includeJars, Visitor<String> visitor) 
    { 
     if (file.isDirectory()) { 
      for (File child : file.listFiles()) { 
       if (!findClasses(root, child, includeJars, visitor)) { 
        return false; 
       } 
      } 
     } else { 
      if (file.getName().toLowerCase().endsWith(".jar") && includeJars) { 
       JarFile jar = null; 
       try { 
        jar = new JarFile(file); 
       } catch (Exception ex) { 

       } 
       if (jar != null) { 
        Enumeration<JarEntry> entries = jar.entries(); 
        while (entries.hasMoreElements()) { 
         JarEntry entry = entries.nextElement(); 
         String name = entry.getName(); 
         int extIndex = name.lastIndexOf(".class"); 
         if (extIndex > 0) { 
          if (!visitor.visit(name.substring(0, extIndex) 
            .replace("/", "."))) { 
           return false; 
          } 
         } 
        } 
       } 
      } else if (file.getName().toLowerCase().endsWith(".class")) { 
       if (!visitor.visit(createClassName(root, file))) { 
        return false; 
       } 
      } 
     } 

     return true; 
    } 

    private static String createClassName(File root, File file) 
    { 
     StringBuffer sb = new StringBuffer(); 
     String fileName = file.getName(); 
     sb.append(fileName.substring(0, fileName.lastIndexOf(".class"))); 
     file = file.getParentFile(); 
     while (file != null && !file.equals(root)) { 
      sb.insert(0, '.').insert(0, file.getName()); 
      file = file.getParentFile(); 
     } 
     return sb.toString(); 
    } 

} 

這裏是忽略JAR文件和剛剛通過的文件回事目錄在classpath一些代碼:

import java.io.File; 

public class Test 
{ 

    public static void main(String[] args) 
    { 
     findClasses(new Visitor<String>() { 

      @Override 
      public boolean visit(String classname) 
      { 
       // apply your filtering here 
       System.out.println(classname); 
       return true; 
      } 
     }); 
    } 

    public interface Visitor<T> 
    { 
     public boolean visit(T t); 
    } 

    public static void findClasses(Visitor<String> visitor) 
    { 
     String classpath = System.getProperty("java.class.path"); 
     String[] paths = classpath.split(System.getProperty("path.separator")); 

     for (String path : paths) { 
      File file = new File(path); 
      // Ignore JAR files, just go through directories on the classpath 
      if (file.isFile()) { 
       continue; 
      } 
      findFiles(file, file, visitor); 
     } 
    } 

    private static boolean findFiles(File root, File file, 
      Visitor<String> visitor) 
    { 
     if (file.isDirectory()) { 
      for (File child : file.listFiles()) { 
       if (!findFiles(root, child, visitor)) { 
        return false; 
       } 
      } 
     } else { 
      if (!visitor.visit(createRelativePath(root, file))) { 
       return false; 
      } 
     } 

     return true; 
    } 

    private static String createRelativePath(File root, File file) 
    { 
     StringBuffer sb = new StringBuffer(); 
     sb.append(file.getName()); 
     file = file.getParentFile(); 
     while (file != null && !file.equals(root)) { 
      sb.insert(0, '/').insert(0, file.getName()); 
      file = file.getParentFile(); 
     } 
     return sb.toString(); 
    } 

} 
+0

我需要更基本的東西。我只有一套我放在資源文件夾中的文件。我只希望我的代碼能夠搜索它們並將其中的一個作爲輸出(基於搜索條件)。 – Andrei

+0

那麼上面的代碼也會查看資源目錄。如果您不關心類路徑中的JAR,則可以刪除瀏覽其內容的代碼。另外,如果你對* .class文件不感興趣,你可以根據需要修改過濾器'endsWith(「。class」)'。 – sebkur