jar文件中的文件夹的路径

时间:2016-05-09 10:08:10

标签: java jar

我有jar文件langdetect.jar。 它具有图像

中显示的层次结构

shows the project structure inside the jar

LanguageDetection个套餐有com/langdetect个班级。 我需要在执行jar文件时从上面的类访问profiles.sm文件夹的路径。

提前致谢。

1 个答案:

答案 0 :(得分:2)

Jars只不过是Zip文件,Java提供了处理这些文件的支持。

Java 6(及更早版本)

您可以将jar文件作为ZipFile打开并迭代它的条目。每个条目在文件中都有一个完整的路径名,没有相对路径名这样的东西。虽然您必须小心,但所有条目 - 尽管在zip文件中是绝对的 - 不是以' /'开头,如果您需要,您必须添加它。以下代码段将为您提供类文件的路径。 className必须以.class结尾,即LanguageDetection.class

String getPath(String jar, String className) throws IOException {
    final ZipFile zf = new ZipFile(jar);
    try {
        for (ZipEntry ze : Collections.list(zf.entries())) {
            final String path = ze.getName();
            if (path.endsWith(className)) {
                final StringBuilder buf = new StringBuilder(path);
                buf.delete(path.lastIndexOf('/'), path.length()); //removes the name of the class to get the path only
                if (!path.startsWith("/")) { //you may omit this part if leading / is not required
                    buf.insert(0, '/');
                }
                return buf.toString();
            }
        }
    } finally {
        zf.close();
    }
    return null;
}

Java 7/8

您可以使用Java7 FileSystem对JAR文件的支持来打开JAR文件。这允许您对jar文件进行操作,就好像它是普通的FileSystem一样。因此,您可以遍历fileTree,直到找到您的文件并从中获取路径。以下示例使用Java8 Streams和Lambdas,Java7的版本可以从此派生,但会更大。

Path jarFile = ...;

Map<String, String> env = new HashMap<String, String>() {{
        put("create", "false");
    }};

try(FileSystem zipFs = newFileSystem(URI.create("jar:" + jarFileFile.toUri()), env)) {
  Optional<Path> path = Files.walk(zipFs.getPath("/"))
                             .filter(p -> p.getFileName().toString().startsWith("LanguageDetection"))
                             .map(Path::getParent)
                             .findFirst();
  path.ifPresent(System.out::println);
}

您的特定问题

以上解决方案用于查找Jar或Zip中的路径,但可能不是解决问题的方法。

我不确定,我是否正确理解你的问题。据我所知,您希望出于任何目的访问类文件夹中的路径。问题是,类/资源查找机制不适用于文件夹,只适用于文件。关闭的概念是一个包,但它始终绑定到一个类。

因此,您始终需要通过getResource()方法访问具体文件。例如MyClass.class.getResource(/path/to/resource.txt)

如果资源位于相对于类及其包的profiles.sm文件夹中,即在/com/languagedetect/profile.sm/中,您可以从引用类构建路径,例如类LanguageDetection在该包中并从中导出绝对路径到profiles.sm路径:

String basePath = "/" + LanguageDetection.class.getPackage().getName().replaceAll("\\.", "/") + "/profiles.sm/";
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt");

如果jar的根目录中只有一个profiles.sm,只需转到

String basePath = "/profiles.sm/";
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt");

如果您有多个/profiles.sm资源的jar,您可以通过类加载器访问所有这些,然后从类的URL中提取Jar文件

for(URL u : Collections.list(LanguageDetection.class.getClassLoader().getResources("/profiles.sm/yourResource"))){
        System.out.println(u);
    }

在任何情况下,如果不访问zip / jar文件,浏览此路径或文件夹的内容,则无法实现,因为Java不支持浏览包内的类或资源/类路径中的文件夹。您可以使用Reflections lib来扩展上面的ClassLoader示例,方法是使用上面的zip示例另外读取检测到的jar的内容。