【发布时间】:2020-01-06 16:52:41
【问题描述】:
我正在尝试将一个文件从我的 JAR 内部复制到 JAR 文件外部的磁盘。我需要复制的文件是大型会计系统的默认配置文件,并且需要在计算机文件系统上。
我搜索了 StackOverflow 以及其他网站(通过 Google 找到)并阅读了大约 50 个答案,我已经尝试了所有这些答案。下面的代码是第一个不是简单地炸毁的代码(使用NullPointerException 或FileNotFoundException),而是实际上试图获取位于 JAR 文件中的资源。
我的 JAR 文件设置如下:
- com.is2300.isis
- MainClass.java(实际名称太长了,我现在不想打出来)
- com.is2300.isis.resources
- 我要复制到磁盘的资源文件的位置
- com.is2300.isis.utils
- 具有文件导出方法的班级
ResourceExporter(下方 - 底部)的位置。
- 具有文件导出方法的班级
我的MainClass.main()入口函数:
public static void main(String[] args) {
// Test our 'utils.ResourceExporter.exportResource(String resourceName)
//+ function.
// Set the start point of our substring to either 5 or 9, depending upon
//+ if we are debugging (in NetBeans) or not (executing the JAR).
if ( isDebugging ) {
startPoint = 5;
} else {
startPoint = 9;
}
// First, we'll try just the name of the resource file to export.
String rsName = "nwind.conf";
try {
System.out.println(ResourceExporter.exportResource(rsName,
MainClass.class, "/home/user/tmp", startPoint));
} catch (Exception ex) {
System.err.println(ex.getCause());
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
// Then, we'll try it with the absolute path.
rsName = "/com/is2300/isis/resources/nwind.conf";
try {
System.out.println(ResourceExporter.exportResource(rsName,
MainClass.class, "/home/user/tmp", startPoint));
} catch (Exception ex) {
System.err.println(ex.getCause());
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
// Then, we'll try it with the relative path.
rsName = "../resources/nwind.conf";
try {
System.out.println(ResourceExporter.exportResource(rsName,
MainClass.class, "/home/user/tmp", startPoint));
} catch (Exception ex) {
System.err.println(ex.getCause());
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
// Last, we'll try it using dots instead of slashes.
rsName = "com.is2300.isis.resources.nwind.conf";
try {
System.out.println(ResourceExporter.exportResource(rsName,
MainClass.class, "/home/user/tmp", startPoint));
} catch (Exception ex) {
System.err.println(ex.getCause());
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
}
我的ResourceExporter.exportResource() 方法:
public static String exportResource(String resourceName, Class cls,
String outPath, int startPoint) throws Exception {
File files = new File(cls.getResource(
cls.getResource(cls.getSimpleName() +
".class").toString().substring(
startPoint, cls.getResource(
cls.getSimpleName() + ".class").toString().lastIndexOf("/")
+ 1)) + "files");
InputStream in = new FileInputStream(files);
FileOutputStream out = new FileOutputStream(outPath +
resourceName.substring(resourceName.lastIndexOf("/")));
int readBytes;
byte[] buffer = new byte[4096];
while ( (readBytes = in.read(buffer)) > 0 )
out.write(buffer, 0, readBytes);
in.close();
out.close();
return files.getAbsolutePath();
}
根据我在public static void main(String[] args) 中所做的事情,我希望对ResourceExporter.exportResource() 方法的调用之一实际上会导致文件被复制。
但是,当我单步执行exportResource() 方法时,在该行之后的每个调用中:
File files = new File(cls.getResource(
cls.getResource(cls.getSimpleName() +
".class").toString().substring(
startPoint, cls.getResource(
cls.getSimpleName() + ".class").toString().lastIndexOf("/")
+ 1)) + "files");
变量files.getCanonicalPath() 调用显示/home/user/Projects/ProjectName/nullfiles,我不明白这是为什么,也不明白这是什么。
【问题讨论】:
-
您到底想用该代码实现什么?假设资源名为“nwind.conf”并且位于包 com.is2300.isis.resources 中。应该发生什么?为什么要使用 FileInputSTream 来读取不是文件,而是 jar 中的类路径资源?
-
@JBNizet,我正在尝试将位于 com.is2300.isis.resources 中的文件从 JAR 复制到硬盘上某个用户确定位置的文件中。实际上,我认为我在最初问题的第一条语句中对此非常简洁:>我正在尝试将 JAR 内部的文件复制到 JAR 文件外部的磁盘。
-
@JBNizet,谢谢!您实际上提示了正确的关键字进入我的大脑。我想我所需要的只是在头部快速踢一脚,而你提供它真是太棒了。这就是为什么我认为编程应该始终是一项团队运动。
-
“我正在尝试从我的 JAR 中复制一个文件..” Jars 中没有没有文件。它们成为资源,必须通过 URL 处理。