Getting a directory inside a .jar

后端 未结 8 1485
悲哀的现实
悲哀的现实 2020-12-11 04:48

I am trying to access a directory inside my jar file. I want to go through every of the files inside the directory itself. I tried, for example, using the following:

<
相关标签:
8条回答
  • 2020-12-11 05:07

    Here is a solution which should work given that you use Java 7... The "trick" is to use the new file API. Oracle JDK provides a FileSystem implementation which can be used to peek into/modify ZIP files, and that include jars!

    Preliminary: grab System.getProperty("java.class.path", "."), split against :; this will give you all entries in your defined classpath.

    First, define a method to obtain a FileSystem out of a classpath entry:

    private static final Map<String, ?> ENV = Collections.emptyMap();
    
    //
    
    private static FileSystem getFileSystem(final String entryName)
        throws IOException
    {
        final String uri = entryName.endsWith(".jar") || entryName.endsWith(".zip"))
            ? "jar:file:" + entryName : "file:" + entryName;
        return FileSystems.newFileSystem(URI.create(uri), ENV);
    }
    

    Then create a method to tell whether a path exists within a filesystem:

    private static boolean pathExists(final FileSystem fs, final String needle)
    {
        final Path path = fs.getPath(needle);
        return Files.exists(path);
    }
    

    Use it to locate your directory.

    Once you have the correct FileSystem, use it to walk your directory using .getPath() as above and open a DirectoryStream using Files.newDirectoryStream().

    And don't forget to .close() a FileSystem once you're done with it!

    Here is a sample main() demonstrating how to read all the root entries of a jar:

    public static void main(final String... args)
        throws IOException
    {
        final Map<String, ?> env = Collections.emptyMap();
        final String jarName = "/opt/sunjdk/1.6/current/jre/lib/plugin.jar";
        final URI uri = URI.create("jar:file:" + jarName);
        final FileSystem fs = FileSystems.newFileSystem(uri, env);
        final Path dir = fs.getPath("/");
        for (Path entry : Files.newDirectoryStream(dir))
            System.out.println(entry);
    }
    
    0 讨论(0)
  • 2020-12-11 05:13

    You can use the PathMatchingResourcePatternResolver provided by Spring.

    public class SpringResourceLoader {
    
        public static void main(String[] args) throws IOException {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    
            // Ant-style path matching
            Resource[] resources = resolver.getResources("/Images/**");
    
            for (Resource resource : resources) {
                System.out.println("resource = " + resource);
                InputStream is = resource.getInputStream();
                BufferedImage img =  ImageIO.read(is);
                System.out.println("img.getHeight() = " + img.getHeight());
                System.out.println("img.getWidth() = " + img.getWidth());
            }
        }
    }
    

    I didn't do anything fancy with the returned Resource but you get the picture.

    Add this to your maven dependency (if using maven):

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>3.1.2.RELEASE</version>
    </dependency>
    

    This will work directly from within Eclipse/NetBeans/IntelliJ and in the jar that's deployed.

    Running from within IntelliJ gives me the following output:

    resource = file [C:\Users\maba\Development\stackoverflow\Q12016222\target\classes\pictures\BMW-R1100S-2004-03.jpg]
    img.getHeight() = 768
    img.getWidth() = 1024
    

    Running from command line with executable jar gives me the following output:

    C:\Users\maba\Development\stackoverflow\Q12016222\target>java -jar Q12016222-1.0-SNAPSHOT.jar
    resource = class path resource [pictures/BMW-R1100S-2004-03.jpg]
    img.getHeight() = 768
    img.getWidth() = 1024
    
    0 讨论(0)
提交回复
热议问题