java - jar 文件内的文件夹路径

标签 java jar

我有 jar 文件 langdetect.jar 。 它具有如图所示的层次结构

shows the project structure inside the jar

有一个类LanguageDetectioncom/langdetect包裹。 我需要访问profiles.sm的路径执行 jar 文件时从上面的类中获取的文件夹。

提前致谢。

最佳答案

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

您可以使用 JAR 文件的 Java7 文件系统支持来打开 JAR 文件。这允许您像操作普通文件系统一样操作 jar 文件。因此,您可以遍历文件树,直到找到文件并从中获取路径。以下示例使用 Java8 Streams 和 Lambda,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 内的路径,但可能无法解决您的问题。

我不确定我是否正确理解你的问题。据我所知,您希望出于任何目的访问类文件夹内的路径。问题是,类/资源查找机制不适用于文件夹,仅适用于文件。接近的概念是包,但它总是绑定(bind)到类。

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

如果资源位于与类及其包相关的 profiles.sm 文件夹中,即在 /com/languagedetect/profile.sm/ 中,您可以构建引用类的路径,例如该包中的类 LanguageDetection 并从中派生到 profile.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");

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

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

无论如何,如果不访问 zip/jar 文件就不可能浏览此路径或文件夹的内容,因为 Java 不支持浏览类路径中的包/文件夹内的类或资源。您可以使用Reflections lib 为此,或者通过使用上面的 zip 示例另外读取检测到的 jar 的内容来扩展上面的 ClassLoader 示例。

关于java - jar 文件内的文件夹路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37113017/

相关文章:

java - PdfBox - 版本 - 文件问题

java - Jar 可执行文件找不到主类 - 很奇怪

java - 如何上传jar到仓库?

java - 如何获取当前运行的jar的路径和名称?

java - 将自定义证书添加到 OkHttp 客户端

java - Eclipse 解决类型错误

java - 打开两个不同的套接字输入流

java - 无法理解为什么这个程序给我这个输出。请解释一下

java - sudo java -jar 与 java -jar

java - 无法构建 JavaFX 应用程序