JAR 从相对位置读取文件,"file:\" 部分在执行 `jar` 时添加但不是作为项目
JAR reading file from relative location, "file:\" part added when execute `jar` but not as project
使用下面这两种方法,我想在我的应用程序中读取 src/com/WindThunderStudio/resources
到 read/load 用户输入的文件:
private void saveInputToFile() {
String[][] input = new String[7][4];
//save data to array
String uri = Constants.INPUT_DATA_PATH;
URL url = getClass().getResource(uri);
File f = null;
System.out.println("Writing data...");
if (url != null) {
System.out.println("Input data path: " + url.getFile());
f = new File(url.getFile());
} else {
System.out.println("URL is null. Searching for parent folder. ");
String uriNoQuery = uri.substring(0, uri.lastIndexOf("/"));
System.out.println("uriNoQuery is: " + uriNoQuery);
url = getClass().getResource(uriNoQuery);
if (url != null) {
f = new File(url.getFile() + File.separator + uri.substring(uri.lastIndexOf("/") + 1, uri.length()));
System.out.println("Supposed file absolute path: " + f.getAbsolutePath());
System.out.println("Supposed file path: " + f.getPath());
} else {
System.out.println("Cannot construct the URL with " + uriNoQuery);
}
}
try {
if (!f.exists()) {
if (f.createNewFile()){
System.out.println("Succeeded in creating file. ");
} else {
System.out.println("Creating file failed. ");
}
}
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(input);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void recoverInputFromFile() {
try {
System.out.println("Reading data...");
String uri = Constants.INPUT_DATA_PATH;
URL url = getClass().getResource(uri);
if (url != null){ //if the URL is found. If not found, is null.
System.out.println("Input data path: " + url.getFile());
File f = new File(url.getFile());
if (f.exists()){
System.out.println("File exists. Path: " + f.getAbsolutePath());
ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
String[][] input = new String[7][4];
input = (String[][])in.readObject();
//recover data from `input`
in.close();
} else {
System.out.println("File doesn't exist. " + url.getFile());
}
} else {
System.out.println("URI is null. " + uri);
}
} catch (Exception e) {
e.printStackTrace();
}
}
,其中
Constants.INPUT_DATA_PATH = "/com/WindThunderStudio/resources/inputData.txt";
当应用程序 运行s 时,它会搜索是否存在具有给定路径的 URL
existante。如果没有,则不执行任何操作。退出时,检查给定的路径是否可以构建URL
的对象,如果不能,则切换到父文件夹,并在该文件夹中创建一个文件,并向其中写入数据。
当运行作为Eclipse中的java项目时,一切正常。第一次:
Reading data...
URI is null. /com/WindThunderStudio/resources/inputData.txt
Writing data...
URL is null. Searching for parent folder.
uriNoQuery is: /com/WindThunderStudio/resources
Supposed file absolute path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Supposed file path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Succeeded in creating file.
并保存数据。第二次 运行ning,数据恢复到 table,我在控制台中得到这些行:
Reading data...
Input data path: /Y:/CtrlRecau_WinSuite_DYL/desarrollo/workspace_NEW/CalSaldoFichaje/bin/com/WindThunderStudio/resources/inputData.txt
File exists. Path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Writing data...
Input data path: /Y:/CtrlRecau_WinSuite_DYL/desarrollo/workspace_NEW/CalSaldoFichaje/bin/com/WindThunderStudio/resources/inputData.txt
但是,如果我将其打包为 运行nable jar(我在打包时选择 Extract library from jar
),我会收到以下错误:
第一次运行宁:
d:\desarrollo>java -jar Cal6.jar
Reading data...
URI is null. /com/WindThunderStudio/resources/inputData.txt
Writing data...
URL is null. Searching for parent folder.
uriNoQuery is: /com/WindThunderStudio/resources
Supposed file absolute path: d:\desarrollo\file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt
Supposed file path: file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt
java.io.IOException: El nombre de archivo, el nombre de directorio o la sintaxis de la etiqueta del volumen no son correctos
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1006)
at com.WindThunderStudio.UI.MainFrame.saveInputToFile(MainFrame.java:777)
at com.WindThunderStudio.UI.MainFrame.windowClosed(MainFrame.java:711)
at java.awt.Window.processWindowEvent(Window.java:2054)
at javax.swing.JFrame.processWindowEvent(JFrame.java:296)
at java.awt.Window.processEvent(Window.java:2009)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access0(EventQueue.java:103)
at java.awt.EventQueue.run(EventQueue.java:706)
at java.awt.EventQueue.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue.run(EventQueue.java:720)
at java.awt.EventQueue.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
西班牙语中的异常原因是指文件名、文件夹名或路径语法错误。
第二次运行ning也是一样,因为上次运行没有写入数据。所以什么都没有存储也没有恢复。
我在执行 jar
文件时注意到 file:\
部分,我认为这是问题所在。我试图去掉常量路径中的前导 /
,但不行。
如果有人能帮助我,那你就太好了。
该项目在 GitHub 中可用:
https://github.com/WesleyBlancoYuan/SWING.git
或者,
git@github.com:WesleyBlancoYuan/SWING.git
最后这些行帮助了我:
//1. read the path of the .class file/JAR. Working in both cases.
String path = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8");
//2. get the parent folder path where the .class file/JAR is located.
//Note: "path" only contains "/", not File.separator, because it's an URL.
String appPath = path.substring(0, lastIndexOf("/"));
//3. Construct a File with the parent folder + separator + file name.
File f = new File(appPath + File.seperator + "someFileName.txt");
然后,检查是否存在等等。
使用下面这两种方法,我想在我的应用程序中读取 src/com/WindThunderStudio/resources
到 read/load 用户输入的文件:
private void saveInputToFile() {
String[][] input = new String[7][4];
//save data to array
String uri = Constants.INPUT_DATA_PATH;
URL url = getClass().getResource(uri);
File f = null;
System.out.println("Writing data...");
if (url != null) {
System.out.println("Input data path: " + url.getFile());
f = new File(url.getFile());
} else {
System.out.println("URL is null. Searching for parent folder. ");
String uriNoQuery = uri.substring(0, uri.lastIndexOf("/"));
System.out.println("uriNoQuery is: " + uriNoQuery);
url = getClass().getResource(uriNoQuery);
if (url != null) {
f = new File(url.getFile() + File.separator + uri.substring(uri.lastIndexOf("/") + 1, uri.length()));
System.out.println("Supposed file absolute path: " + f.getAbsolutePath());
System.out.println("Supposed file path: " + f.getPath());
} else {
System.out.println("Cannot construct the URL with " + uriNoQuery);
}
}
try {
if (!f.exists()) {
if (f.createNewFile()){
System.out.println("Succeeded in creating file. ");
} else {
System.out.println("Creating file failed. ");
}
}
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(input);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void recoverInputFromFile() {
try {
System.out.println("Reading data...");
String uri = Constants.INPUT_DATA_PATH;
URL url = getClass().getResource(uri);
if (url != null){ //if the URL is found. If not found, is null.
System.out.println("Input data path: " + url.getFile());
File f = new File(url.getFile());
if (f.exists()){
System.out.println("File exists. Path: " + f.getAbsolutePath());
ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
String[][] input = new String[7][4];
input = (String[][])in.readObject();
//recover data from `input`
in.close();
} else {
System.out.println("File doesn't exist. " + url.getFile());
}
} else {
System.out.println("URI is null. " + uri);
}
} catch (Exception e) {
e.printStackTrace();
}
}
,其中
Constants.INPUT_DATA_PATH = "/com/WindThunderStudio/resources/inputData.txt";
当应用程序 运行s 时,它会搜索是否存在具有给定路径的 URL
existante。如果没有,则不执行任何操作。退出时,检查给定的路径是否可以构建URL
的对象,如果不能,则切换到父文件夹,并在该文件夹中创建一个文件,并向其中写入数据。
当运行作为Eclipse中的java项目时,一切正常。第一次:
Reading data...
URI is null. /com/WindThunderStudio/resources/inputData.txt
Writing data...
URL is null. Searching for parent folder.
uriNoQuery is: /com/WindThunderStudio/resources
Supposed file absolute path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Supposed file path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Succeeded in creating file.
并保存数据。第二次 运行ning,数据恢复到 table,我在控制台中得到这些行:
Reading data...
Input data path: /Y:/CtrlRecau_WinSuite_DYL/desarrollo/workspace_NEW/CalSaldoFichaje/bin/com/WindThunderStudio/resources/inputData.txt
File exists. Path: Y:\CtrlRecau_WinSuite_DYL\desarrollo\workspace_NEW\CalSaldoFichaje\bin\com\WindThunderStudio\resources\inputData.txt
Writing data...
Input data path: /Y:/CtrlRecau_WinSuite_DYL/desarrollo/workspace_NEW/CalSaldoFichaje/bin/com/WindThunderStudio/resources/inputData.txt
但是,如果我将其打包为 运行nable jar(我在打包时选择 Extract library from jar
),我会收到以下错误:
第一次运行宁:
d:\desarrollo>java -jar Cal6.jar
Reading data...
URI is null. /com/WindThunderStudio/resources/inputData.txt
Writing data...
URL is null. Searching for parent folder.
uriNoQuery is: /com/WindThunderStudio/resources
Supposed file absolute path: d:\desarrollo\file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt
Supposed file path: file:\D:\desarrollo\Cal6.jar!\com\WindThunderStudio\resources\inputData.txt
java.io.IOException: El nombre de archivo, el nombre de directorio o la sintaxis de la etiqueta del volumen no son correctos
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1006)
at com.WindThunderStudio.UI.MainFrame.saveInputToFile(MainFrame.java:777)
at com.WindThunderStudio.UI.MainFrame.windowClosed(MainFrame.java:711)
at java.awt.Window.processWindowEvent(Window.java:2054)
at javax.swing.JFrame.processWindowEvent(JFrame.java:296)
at java.awt.Window.processEvent(Window.java:2009)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access0(EventQueue.java:103)
at java.awt.EventQueue.run(EventQueue.java:706)
at java.awt.EventQueue.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue.run(EventQueue.java:720)
at java.awt.EventQueue.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
西班牙语中的异常原因是指文件名、文件夹名或路径语法错误。
第二次运行ning也是一样,因为上次运行没有写入数据。所以什么都没有存储也没有恢复。
我在执行 jar
文件时注意到 file:\
部分,我认为这是问题所在。我试图去掉常量路径中的前导 /
,但不行。
如果有人能帮助我,那你就太好了。
该项目在 GitHub 中可用:
https://github.com/WesleyBlancoYuan/SWING.git
或者,
git@github.com:WesleyBlancoYuan/SWING.git
最后这些行帮助了我:
//1. read the path of the .class file/JAR. Working in both cases.
String path = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8");
//2. get the parent folder path where the .class file/JAR is located.
//Note: "path" only contains "/", not File.separator, because it's an URL.
String appPath = path.substring(0, lastIndexOf("/"));
//3. Construct a File with the parent folder + separator + file name.
File f = new File(appPath + File.seperator + "someFileName.txt");
然后,检查是否存在等等。