我有一个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文件?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在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
直接位于顶层目录下,如果它位于嵌套目录中,你需要相应地调整路径。此外,确保你有权限写入目标目录,并且目标路径是有效的。