viaclectic viaclectic - 5 months ago 30
Java Question

Get a list of resources from classpath directory

I am looking for a way to get a list of all resource names from a given classpath directory, something like a method

List<String> getResourceNames (String directoryName)
.

For example, given a classpath directory
x/y/z
containing files
a.html
,
b.html
,
c.html
and a subdirectory
d
,
getResourceNames("x/y/z")
should return a
List<String>
containing the following strings:
['a.html', 'b.html', 'c.html', 'd']
.

It should work both for resources in filesystem and jars.

I know that I can write a quick snippet with
File
s,
JarFile
s and
URL
s, but I do not want to reinvent the wheel. My question is, given existing publicly available libraries, what is the quickest way to implement
getResourceNames
? Spring and Apache Commons stacks are both feasible.

Answer

Custom Scanner

Implement your own scanner. For example:

  private List<String> getResourceFiles( String path ) throws IOException {
    List<String> filenames = new ArrayList<>();

    try(
      InputStream in = getResourceAsStream( path );
      BufferedReader br = new BufferedReader( new InputStreamReader( in ) ) ) {
      String resource;

      while( (resource = br.readLine()) != null ) {
        filenames.add( resource );
      }
    }

    return filenames;
  }

  private InputStream getResourceAsStream( String resource ) {
    final InputStream in
      = getContextClassLoader().getResourceAsStream( resource );

    return in == null ? getClass().getResourceAsStream( resource ) : in;
  }

  private ClassLoader getContextClassLoader() {
    return Thread.currentThread().getContextClassLoader();
  }

Spring Framework

Use PathMatchingResourcePatternResolver from Spring Framework.

Google Reflections

The other techniques might be slow at runtime for huge CLASSPATH values. A faster solution is to use Google's Reflections API, which precompiles the search at compile time.