获取.jar中的目录

时间:2011-04-29 09:54:10

标签: java url jar applet directory

我正在尝试访问jar文件中的目录。 我想浏览目录中的每个文件。例如,我尝试使用以下内容:

URL imagesDirectoryURL=getClass().getClassLoader().getResource("Images");

if(imagesFolderURL!=null)
{
    File imagesDirectory= new File(imagesDirectoryURL.getFile());
}

如果我测试这个小程序,它运行良好。但是,一旦我把内容放入罐子里,它就不会因为几个原因了。 如果我使用此代码,则URL始终指向jar外部,因此我必须将Images目录放在那里。 但是如果我使用new File(imagesDirectoryURL.toURI());,它在jar中不起作用,因为我收到错误URI not hierarchical。我确定该目录存在于jar中。 我怎么能在jar里面得到Images的内容?

8 个答案:

答案 0 :(得分:5)

Jars中的路径是路径,而不是实际目录,因为您可以在文件系统上使用它们。要获取Jar文件的特定路径中的所有资源:

  • 获得指向Jar的URL
  • InputStream获取URL
  • ZipInputStream
  • 构建InputStream
  • 迭代每个ZipEntry,查找与所需路径的匹配项。
  

..当它不在那个罐子里面时,我还能测试我的Applet吗?或者我是否需要编程两种方式来获取我的图像?

ZipInputStream不适用于文件系统目录中的松散资源。但是,我强烈建议使用像Ant这样的构建工具来构建(编译/ jar / sign等)applet。编写构建脚本可能需要一个小时左右的时间。检查它,但此后你可以通过几次击键和几秒钟来构建项目。

  

如果我想要测试我的Aplet,我总是需要提取并签名我的jar,这会很烦人

我不确定你的意思。 “提取物”在哪里进入?如果我不清楚,沙盒子小程序可以从archive属性中提到的任何Jar加载资源。您可能要做的另一件事是将资源Jar(s)与小程序Jar分开。资源通常比代码更改,因此您的构建可能会采取一些快捷方式。

  

我认为我必须考虑将我的图像放入jar之外的单独目录中。

如果您的意思是在服务器上,没有实用的方法来获取服务器提供的帮助之外的图像文件列表。例如。某些服务器设置不安全,无法为任何没有默认文件的目录(例如index.html)生成基于HTML的“文件列表”。


  

我只有一个罐子,里面有我的课程,图像和声音。

好的 - 考虑移动声音&图像变成一个单独的罐子。或者至少,将它们放入带有“无压缩”的罐子中。虽然Zip压缩技术适用于类,但它们在压缩(否则已经压缩)的媒体格式方面效率较低。

  

我必须签名,因为我使用“首选项”类来保存用户设置。“

小程序的Preferences还有其他替代方法,例如Cookie。对于插件2架构小程序,您可以使用Java Web Start启动小程序(仍然嵌入在浏览器中)。 JWS提供PersistenceService。这是我的小demo. of the PersistenceService

说到JWS,这让我想到:你是否绝对肯定这个游戏会更好用作applet,而不是使用JWS启动的应用程序(例如使用JFrame)?

Applets将给你带来压力,JWS提供了PersistenceService,因为它是在Java 1.2中引入的。

答案 1 :(得分:4)

这是一个解决方案,应该可以使用Java 7 ...“技巧”是使用新的文件API。 Oracle JDK提供了FileSystem实现,可用于查看/修改ZIP文件,包括jar文件!

初步:抓住System.getProperty("java.class.path", "."),与:分开;这将为您提供已定义的类路径中的所有条目。

首先,定义一个从类路径条目中获取FileSystem的方法:

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);
}

然后创建一个方法来判断文件系统中是否存在路径:

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

用它来找到你的目录。

如果您拥有正确的FileSystem,请使用它来如上所述使用.getPath()浏览您的目录,并使用DirectoryStream打开Files.newDirectoryStream()

一旦你完成它,不要忘记.close() FileSystem

这是一个示例main(),演示了如何读取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);
}

答案 2 :(得分:1)

您可以使用Spring提供的PathMatchingResourcePatternResolver

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());
        }
    }
}

我没有对返回的Resource做任何想象,但是你得到了照片。

将此添加到您的maven依赖项(如果使用maven):

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

这将直接在已部署的jar中的Eclipse / NetBeans / IntelliJ 中使用。

从IntelliJ内部运行,给出了以下输出:

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

从带有可执行jar的命令行运行,给出了以下输出:

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

答案 3 :(得分:0)

我认为您可以直接访问ZIP / JAR文件中的资源 请参阅教程,为您的问题提供解决方案

How to extract Java resources from JAR and zip archives

希望有所帮助

答案 4 :(得分:0)

如果我理解你的问题,你想检查jar里面的目录并检查那个目录里面的所有文件。你可以这样做:

JarInputStream jar = new JarInputStream(new FileInputStream("D:\\x.jar"));
    JarEntry jarEntry ;
    while(true)
        {
         jarEntry = jar.getNextJarEntry();
         if(jarEntry != null)
         {

            if(jarEntry.isDirectory() == false)
            {
        String str = jarEntry.getName();
                if(str.startsWith("weblogic/xml/saaj"))
        {
            anything which comes here are inside weblogic\xml\saaj directory
        }
        }

     }
    }    

答案 5 :(得分:0)

你在这里寻找的可能是Jar的JarEntry列表...我在研究生院期间做过类似的工作......你可以在这里获得修改后的课程(http://code.google.com/p/marcellodesales-cs-research/source/browse/trunk/grad-ste-ufpe-brazil/ptf-add-on-dev/src/br/ufpe/cin/stp/global/filemanager/JarFileContentsLoader.java)注意URL包含一个不使用Generics的旧Java类......

对于给定的令牌,此类返回一组带有协议“jar:file:/”的URL ...

package com.collabnet.svnedge.discovery.client.browser.util;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarFileContentsLoader {

    private JarFile jarFile;

    public JarFileContentsLoader(String jarFilePath) throws IOException {
        this.jarFile = new JarFile(jarFilePath);
    }

    /**
     * @param existingPath an existing path string inside the jar.
     * @return the set of URL's from inside the Jar (whose protocol is "jar:file:/"
     */
    public Set<URL> getDirEntries(String existingPath) {
        Set<URL> set = new HashSet<URL>();
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            String element = entries.nextElement().getName();
            URL url = getClass().getClassLoader().getResource(element);
            if (url.toString().contains("jar:file")
                    && !element.contains(".class")
                    && element.contains(existingPath)) {
                set.add(url);
            }
        }
        return set;
    }

    public static void main(String[] args) throws IOException {
        JarFileContentsLoader jarFileContents = new JarFileContentsLoader(
                "/u1/svnedge-discovery/client-browser/lib/jmdns.jar");
        Set<URL> entries = jarFileContents.getDirEntries("impl");
        Iterator<URL> a = entries.iterator();
        while (a.hasNext()) {
            URL element = a.next();
            System.out.println(element);
        }
    }

}

输出结果为:

jar:file:/u1/svnedge-discovery/client-browser/lib/jmdns.jar!/javax/jmdns/impl/constants/
jar:file:/u1/svnedge-discovery/client-browser/lib/jmdns.jar!/javax/jmdns/impl/tasks/state/
jar:file:/u1/svnedge-discovery/client-browser/lib/jmdns.jar!/javax/jmdns/impl/tasks/resolver/
jar:file:/u1/svnedge-discovery/client-browser/lib/jmdns.jar!/javax/jmdns/impl/
jar:file:/u1/svnedge-discovery/client-browser/lib/jmdns.jar!/javax/jmdns/impl/tasks/

答案 6 :(得分:0)

以下代码示例可以帮助您

   Enumeration<URL> inputStream = BrowserFactory.class.getClassLoader().getResources(".");
        System.out.println("INPUT STREAM ==> "+inputStream);
        System.out.println(inputStream.hasMoreElements());
        while (inputStream.hasMoreElements()) {
            URL url = (URL) inputStream.nextElement();
            System.out.println(url.getFile());
        }

答案 7 :(得分:0)

如果您真的想要处理目录等JAR文件,请查看TrueZIP 7。可能是您想要的以下内容:

URL url = ... // whatever
URI uri = url.toURI();
TFile file = new TFile(uri); // File-look-alike in TrueZIP 7
if (file.isDirectory) // true for regular directories AND JARs if the module truezip-driver-file is on the class path
    for (TFile entry : file.listFiles()) // iterate top level directory
         System.out.println(entry.getPath()); // or whatever

此致 基督教