web-dev-qa-db-ja.com

ClassLoader.getResources()を正しく使用するには?

ClassLoader.getResources()を使用して、クラスパスから再帰的にリソースを見つけるにはどうすればよいですか?

例えば。

  • META-INF "ディレクトリ"内のすべてのリソースの検索:次のようなものを想像してください

    getClass().getClassLoader().getResources("META-INF")

    残念ながら、これはまさにこの「ディレクトリ」へのURLのみを取得します。

  • bla.xmlという名前のすべてのリソース(再帰的に)

    getClass().getClassLoader().getResources("bla.xml")

    しかし、これは空のEnumerationを返します。

そしておまけの質問として:ClassLoader.getResources()ClassLoader.getResource()とどう違うのですか?

76
MRalwasser

クラスパスを再帰的に検索する方法はありません。この方法でリソースを取得するには、リソースのフルパス名を知る必要があります。リソースはファイルシステムまたはjarファイルのディレクトリにあるため、「クラスパス」のディレクトリリストを実行するほど単純ではありません。リソースの完全なパスを指定する必要があります。 「/com/mypath/bla.xml」。

2番目の質問では、getResourceは、指定されたリソース名に一致する最初のリソースを返します。クラスパスの検索順序は getResourceのjavadoc で指定されています

19
krock

Spring Frameworkには、クラスパスを再帰的に検索できるクラスがあります。

PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
resolver.getResources("classpath*:some/package/name/**/*.xml");
34
rec

これは、特定のURLオブジェクトが指しているFileオブジェクトを取得する最も簡単な方法です。

File file=new File(url.toURI());

さて、あなたの具体的な質問について:

  • mETA-INF「ディレクトリ」内のすべてのリソースを検索します。

実際、このURLを指すFileオブジェクトを取得できます。

Enumeration<URL> en=getClass().getClassLoader().getResources("META-INF");
if (en.hasMoreElements()) {
    URL metaInf=en.nextElement();
    File fileMetaInf=new File(metaInf.toURI());

    File[] files=fileMetaInf.listFiles();
    //or 
    String[] filenames=fileMetaInf.list();
}
  • bla.xmlという名前のすべてのリソース(再帰的に)

この場合、いくつかのカスタムコードを実行する必要があります。ダミーの例を次に示します。

final List<File> foundFiles=new ArrayList<File>();

FileFilter customFilter=new FileFilter() {
    @Override
    public boolean accept(File pathname) {

        if(pathname.isDirectory()) {
            pathname.listFiles(this);
        }
        if(pathname.getName().endsWith("bla.xml")) {
            foundFiles.add(pathname);
            return true;
        }
        return false;
    }

};      
//rootFolder here represents a File Object pointing the root forlder of your search 
rootFolder.listFiles(customFilter);

コードが実行されると、見つかったすべてのオカレンスがfoundFilesリストに表示されます。

19
Tomas Narros

ベストスの答えに基づいたコードは次のとおりです。

    Enumeration<URL> en = getClass().getClassLoader().getResources(
            "META-INF");
    List<String> profiles = new ArrayList<>();
    if (en.hasMoreElements()) {
        URL url = en.nextElement();
        JarURLConnection urlcon = (JarURLConnection) (url.openConnection());
        try (JarFile jar = urlcon.getJarFile();) {
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                String entry = entries.nextElement().getName();
                System.out.println(entry);
            }
        }
    }
9
Mark Butler

MRalwasser、ヒントをあげて、URL.getConnection()JarURLConnectionにキャストします。次に、JarURLConnection.getJarFile()を使用します。 JarFileがあり、内部のリソースに自由にアクセスできます。

残りはあなたに任せます。

お役に立てれば!

5
bestsss