![](/img/trans.png)
[英]Why am I getting this weird output when creating a JAR file from commandline?
[英]Why am I getting 'nullfiles' when trying to copy a file from inside a jar to disk?
我正在嘗試將JAR文件外部的文件從JAR內部復制到磁盤。 我將需要復制的文件是大型記帳系統的默認配置文件,並且在計算機文件系統上是必需的。
我搜索了StackOverflow以及其他網站(與Google一起找到的網站),並閱讀了大約五十個答案,我已經嘗試了所有答案。 下面的代碼是第一個沒有被簡單炸毀的代碼(使用NullPointerException
或FileNotFoundException
),而是實際上試圖獲取位於JAR文件中的資源。
我的JAR文件設置如下:
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
,我不明白為什么這樣,也不是什么。
@JBNizet和@AndrewThompson:
謝謝你們的評論。 特別是@JBNizet! 您快速地踢了我一下腦袋,使我更加仔細地閱讀了所寫的內容,並立即發現了問題。 非常感謝你。
解決方法是:我沒有做復雜的事情:
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("/")));
我大約10年前寫的,不記得我在想什么,我能夠簡化為:
InputStream in = ClassLoader.getSystemClassLoader().getSystemResourceAsStream(resourceName);
FileOutputStream out = new FileOutputStream(outPath +
resourceName.substring(resourceName.lastIndexOf("/")));
現在,“文件”(表示對@AndrewThompson進行的語義更正)位於JAR文件中。
但是,這不是必須要做的唯一更改。 我在哪里設置傳遞給參數resourceName
的變量,也不正確。 我有這樣設置:
String rsName = "/com/is2300/isis/resources/nwind.conf";
但是,不應在前面加上斜杠(/)。 一旦我將上面的行更改為:
String rsName = "com/is2300/isis/resources/nwind.conf";
一切都按照我的預期進行。
再次感謝這兩個評論。 感謝您的想法和協助,以使我的大腦參與其中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.