开发者社区 问答 正文

以编程方式从另一个运行中的JAR文件复制一个JAR文件

我有一个JAR(resource.jar)文件作为资源包含在另一个正在运行的JAR文件(app.jar)中,我想以编程方式将resource.jar文件复制到app.jar以及计算机上的其他位置(例如,桌面)。

但是,由于某种原因,我无法执行此操作-每当我尝试执行任何操作来访问resource.jar时(例如打开流),都会出现错误,好像文件不在那里一样。但是,如果我使用完全相同的代码来复制不同类型的文件(例如.txt文件),那么一切都会顺利进行。

例如,拿app.jar,它包含三个文件:Main.class,resource.jar,和test.txt

例如,这可能是app.jar的代码

public class Main{
    public static void main(String[] args){
        File destination; // something outside of the JAR file

        URL resourceURL = Main.class.getResource("/resource.jar");
        InputStream resourceStream = Main.class.getResourceAsStream("/resource.jar");

        // resourceURL and testStream are null

        URL testURL = Main.class.getResource("/test.txt");
        InputStream testStream = Main.class.getResourceAsStream("/test.txt");

        // testURL and testStream are NOT null
    }
}

我认为也许只是删除甚至更改resource.jar的扩展名都可以解决此问题,但没有效果。

如何从一个正在运行的JAR文件中复制一个JAR文件?

展开
收起
几许相思几点泪 2019-12-22 18:38:45 883 分享 版权
阿里云 AI 助理回答

在Java中,从一个运行中的JAR文件中访问并复制内部的JAR文件确实需要一些特殊处理,因为getResource()getResourceAsStream()方法主要用于获取类路径资源的内容,而不是直接操作这些资源作为文件。对于像.jar这样的嵌套资源,你需要通过输入流读取其内容,然后以字节流的形式写入到目标位置。

以下是一个示例代码,展示了如何将嵌入的resource.jar从正在运行的app.jar中提取并复制到指定目录:

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Main {
    public static void main(String[] args) {
        String destinationPath = "path/to/destination/resource.jar"; // 指定要复制到的目标路径

        try (InputStream resourceStream = Main.class.getResourceAsStream("/resource.jar")) {
            if (resourceStream == null) {
                System.out.println("Failed to find resource.jar in the classpath.");
                return;
            }

            // 由于resource.jar是嵌套在另一个jar中,我们需要通过ZipInputStream来处理
            ZipInputStream zipIn = new ZipInputStream(resourceStream);
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                if (entry.getName().equals("resource.jar")) {
                    Files.copy(zipIn, Paths.get(destinationPath), StandardCopyOption.REPLACE_EXISTING);
                    System.out.println("resource.jar has been extracted to: " + destinationPath);
                    break;
                }
            }
            zipIn.closeEntry();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这段代码首先尝试通过getResourceAsStream()获取resource.jar的输入流。一旦获得输入流,它就使用ZipInputStream来遍历这个输入流(因为它实际上是来自一个ZIP文件内部的条目),寻找名为resource.jar的条目,并将其内容复制到指定的文件系统路径上。

请注意,此代码假设resource.jar直接位于顶层目录下,如果它位于嵌套目录中,你需要相应地调整路径。此外,确保你有权限写入目标目录,并且目标路径是有效的。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: