运行 Jar 时找不到文件
File not found when running Jar
我正在做一个非常小的 java 项目,我在其中从 JSON 文件加载应用程序设置,在 IDE (IntelliJ) 中一切正常,找到文件并正常工作,但是当我构建 jar 并从命令行执行它时,它会抛出 FileNotFoundException。
可能是什么原因造成的?
这是我的一些代码:
1- 通过这个 class,我得到了 JSON 文件的路径:
package sample.Utils;
public class JsonFilePLace {
private final String JSONPATH;
public JsonFilePLace(){
JSONPATH = getClass().getResource("/sample/data/loadData.json").getPath();
String path = getClass().getResource("/sample/data/loadData.json").getPath();
System.out.println(path);
}
public String getJSONPATH() {
return JSONPATH;
}
}
这是读取 JSON 文件的新方法:
public class JsonParsers {
static String fileContent;
public JsonParsers() throws URISyntaxException, IOException {
final URL resource = this.getClass().getResource("/loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
fileContent = new String(bytes);
}
public static SettingsObject getSettings(/*String filePath*/) {
JSONParser jparser = new JSONParser();
SettingsObject returnedObject = null;
try {
Object object = jparser.parse(/*new FileReader(filePath)*/fileContent);
JSONObject jObject = (JSONObject) object;
String name = (String) jObject.get("user");
String matricule = (String) jObject.get("matricule");
JSONArray jArray = (JSONArray) jObject.get("tarifaction");
FormulaClass A = null, B = null, C = null;
int counter = 0;
for (Object obj : jArray) {
JSONObject jObj = (JSONObject) obj;
if (counter == 0)
A = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
if (counter == 1)
B = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
if (counter == 2)
C = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
counter++;
}
JSONObject staticsObject = (JSONObject) jObject.get("statics");
String reservation_1 = String.valueOf(staticsObject.get("reservation_1"));
String reservation_2 = String.valueOf(staticsObject.get("reservation_2"));
String prise_charge = (String.valueOf(staticsObject.get("prise_charge")));
String tva = String.valueOf(staticsObject.get("tva"));
String savePath = (String) jObject.get("save_path");
returnedObject = new SettingsObject(name, matricule, A, B, C, reservation_1, reservation_2, prise_charge, tva, savePath);
} catch (ParseException e) {
e.printStackTrace();
}
return returnedObject;
}
这是主要方法:
public class 主要扩展应用程序 {
// TODO: 19/03/2019 maybe instanciate the settings variable here
public static final String JSONPATH = "loadData.json";
public static SettingsObject GLOBAL_SETTINGS;
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("uis/sample.fxml"));
primaryStage.setTitle("Taxi Manager");
primaryStage.setScene(new Scene(root, 820, 766));
primaryStage.centerOnScreen();
primaryStage.show();
}
public static void main(String[] args) throws IOException, URISyntaxException {
JsonParsers jparsers = new JsonParsers();
GLOBAL_SETTINGS = jparsers.getSettings();
launch(args);
}
}
这是 cmd 错误,从编辑器中知道它运行正常:
C:\Users\Simou\Desktop\Work\WorK\TaxiProgram\out\artifacts\TaxiProgramFr>java -j
ar TaxiProgramFr.jar
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Lau
ncherImpl.java:389)
at
com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImp
l.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.nio.file.FileSystemNotFoundException
at
com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemPr
ovider.java:171)
at
com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider
.java:157)
at java.nio.file.Paths.get(Unknown Source)
at sample.Utils.JsonParsers.<init>(JsonParsers.java:24)
at sample.Main.main(Main.java:36)
... 11 more
Exception running application sample.Main
这是写法:
public static void settingsWriter(SettingsObject settings, String filePath) {
JSONObject gObj = new JSONObject();
JSONArray jsonArray = new JSONArray();
JSONObject staticsOBJ = new JSONObject();
gObj.put("user", settings.getUserName());
gObj.put("matricule", settings.getMatricule());
JSONObject tempObj = new JSONObject();
tempObj.put("distance", settings.getA().getDistance());
tempObj.put("heure", settings.getA().getHeure() * 60);
jsonArray.add(tempObj);
tempObj = new JSONObject();
tempObj.put("distance", settings.getB().getDistance());
tempObj.put("heure", settings.getB().getHeure() * 60);
jsonArray.add(tempObj);
tempObj = new JSONObject();
tempObj.put("distance", settings.getC().getDistance());
tempObj.put("heure", settings.getC().getHeure() * 60);
jsonArray.add(tempObj);
gObj.put("tarifaction", jsonArray);
staticsOBJ.put("reservation_1", Integer.parseInt(settings.getReservation_1()));
staticsOBJ.put("reservation_2", Integer.parseInt(settings.getReservation_2()));
staticsOBJ.put("prise_charge", Double.parseDouble(settings.getPrise_Charge()));
staticsOBJ.put("tva", Integer.parseInt(settings.getTva()));
gObj.put("statics", staticsOBJ);
gObj.put("save_path", settings.getPathSave());
File jsonFile = new File(filePath);
try {
FileWriter fileWriter = new FileWriter(jsonFile);
fileWriter.write(gObj.toJSONString());
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
您正在将文本文件存储在源代码包中。因此,该文件很可能会在编译过程中被删除,除非您明确配置为不这样做。
如果您还想将它们存储在那里,您需要做的是
final URL resource = YourClass.class.getResource("/sample/data/loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);
YourClass.class.getResource("/sample/data/loadData.json");
这里/sample/data/loadData.json
是包的绝对路径
我建议将这些文件存储在 resource
文件夹下。
YourClass.class.getResource("loadData.json");
你需要做的就是删除JsonFilePLace
,根本不需要!
改为这样做
final URL resource = YourClass.class.getResource("loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);
final Object object = jparser.parse(fileContent);
final JSONObject jObject = (JSONObject) object;
因为这似乎不起作用,直接访问 File
资源
try (final InputStream is = YourClass.class.getResourceAsStream("loadData.json")) {
final String fileContent = readString(is);
final Object object = jparser.parse(fileContent);
final JSONObject jObject = (JSONObject) object;
...
}
private static String readString(final InputStream inputStream) throws IOException {
final ByteArrayOutputStream result = new ByteArrayOutputStream();
final byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8);
}
我正在做一个非常小的 java 项目,我在其中从 JSON 文件加载应用程序设置,在 IDE (IntelliJ) 中一切正常,找到文件并正常工作,但是当我构建 jar 并从命令行执行它时,它会抛出 FileNotFoundException。 可能是什么原因造成的?
这是我的一些代码:
1- 通过这个 class,我得到了 JSON 文件的路径:
package sample.Utils;
public class JsonFilePLace {
private final String JSONPATH;
public JsonFilePLace(){
JSONPATH = getClass().getResource("/sample/data/loadData.json").getPath();
String path = getClass().getResource("/sample/data/loadData.json").getPath();
System.out.println(path);
}
public String getJSONPATH() {
return JSONPATH;
}
}
这是读取 JSON 文件的新方法:
public class JsonParsers {
static String fileContent;
public JsonParsers() throws URISyntaxException, IOException {
final URL resource = this.getClass().getResource("/loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
fileContent = new String(bytes);
}
public static SettingsObject getSettings(/*String filePath*/) {
JSONParser jparser = new JSONParser();
SettingsObject returnedObject = null;
try {
Object object = jparser.parse(/*new FileReader(filePath)*/fileContent);
JSONObject jObject = (JSONObject) object;
String name = (String) jObject.get("user");
String matricule = (String) jObject.get("matricule");
JSONArray jArray = (JSONArray) jObject.get("tarifaction");
FormulaClass A = null, B = null, C = null;
int counter = 0;
for (Object obj : jArray) {
JSONObject jObj = (JSONObject) obj;
if (counter == 0)
A = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
if (counter == 1)
B = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
if (counter == 2)
C = new FormulaClass((double) jObj.get("distance"), (double) jObj.get("heure"));
counter++;
}
JSONObject staticsObject = (JSONObject) jObject.get("statics");
String reservation_1 = String.valueOf(staticsObject.get("reservation_1"));
String reservation_2 = String.valueOf(staticsObject.get("reservation_2"));
String prise_charge = (String.valueOf(staticsObject.get("prise_charge")));
String tva = String.valueOf(staticsObject.get("tva"));
String savePath = (String) jObject.get("save_path");
returnedObject = new SettingsObject(name, matricule, A, B, C, reservation_1, reservation_2, prise_charge, tva, savePath);
} catch (ParseException e) {
e.printStackTrace();
}
return returnedObject;
}
这是主要方法:
public class 主要扩展应用程序 {
// TODO: 19/03/2019 maybe instanciate the settings variable here
public static final String JSONPATH = "loadData.json";
public static SettingsObject GLOBAL_SETTINGS;
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("uis/sample.fxml"));
primaryStage.setTitle("Taxi Manager");
primaryStage.setScene(new Scene(root, 820, 766));
primaryStage.centerOnScreen();
primaryStage.show();
}
public static void main(String[] args) throws IOException, URISyntaxException {
JsonParsers jparsers = new JsonParsers();
GLOBAL_SETTINGS = jparsers.getSettings();
launch(args);
}
}
这是 cmd 错误,从编辑器中知道它运行正常:
C:\Users\Simou\Desktop\Work\WorK\TaxiProgram\out\artifacts\TaxiProgramFr>java -j
ar TaxiProgramFr.jar
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Lau
ncherImpl.java:389)
at
com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImp
l.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.nio.file.FileSystemNotFoundException
at
com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemPr
ovider.java:171)
at
com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider
.java:157)
at java.nio.file.Paths.get(Unknown Source)
at sample.Utils.JsonParsers.<init>(JsonParsers.java:24)
at sample.Main.main(Main.java:36)
... 11 more
Exception running application sample.Main
这是写法:
public static void settingsWriter(SettingsObject settings, String filePath) {
JSONObject gObj = new JSONObject();
JSONArray jsonArray = new JSONArray();
JSONObject staticsOBJ = new JSONObject();
gObj.put("user", settings.getUserName());
gObj.put("matricule", settings.getMatricule());
JSONObject tempObj = new JSONObject();
tempObj.put("distance", settings.getA().getDistance());
tempObj.put("heure", settings.getA().getHeure() * 60);
jsonArray.add(tempObj);
tempObj = new JSONObject();
tempObj.put("distance", settings.getB().getDistance());
tempObj.put("heure", settings.getB().getHeure() * 60);
jsonArray.add(tempObj);
tempObj = new JSONObject();
tempObj.put("distance", settings.getC().getDistance());
tempObj.put("heure", settings.getC().getHeure() * 60);
jsonArray.add(tempObj);
gObj.put("tarifaction", jsonArray);
staticsOBJ.put("reservation_1", Integer.parseInt(settings.getReservation_1()));
staticsOBJ.put("reservation_2", Integer.parseInt(settings.getReservation_2()));
staticsOBJ.put("prise_charge", Double.parseDouble(settings.getPrise_Charge()));
staticsOBJ.put("tva", Integer.parseInt(settings.getTva()));
gObj.put("statics", staticsOBJ);
gObj.put("save_path", settings.getPathSave());
File jsonFile = new File(filePath);
try {
FileWriter fileWriter = new FileWriter(jsonFile);
fileWriter.write(gObj.toJSONString());
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
您正在将文本文件存储在源代码包中。因此,该文件很可能会在编译过程中被删除,除非您明确配置为不这样做。
如果您还想将它们存储在那里,您需要做的是
final URL resource = YourClass.class.getResource("/sample/data/loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);
YourClass.class.getResource("/sample/data/loadData.json");
这里/sample/data/loadData.json
是包的绝对路径
我建议将这些文件存储在 resource
文件夹下。
YourClass.class.getResource("loadData.json");
你需要做的就是删除JsonFilePLace
,根本不需要!
改为这样做
final URL resource = YourClass.class.getResource("loadData.json");
final Path path = Paths.get(resource.toURI());
final byte[] bytes = Files.readAllBytes(path);
final String fileContent = new String(bytes);
final Object object = jparser.parse(fileContent);
final JSONObject jObject = (JSONObject) object;
因为这似乎不起作用,直接访问 File
资源
try (final InputStream is = YourClass.class.getResourceAsStream("loadData.json")) {
final String fileContent = readString(is);
final Object object = jparser.parse(fileContent);
final JSONObject jObject = (JSONObject) object;
...
}
private static String readString(final InputStream inputStream) throws IOException {
final ByteArrayOutputStream result = new ByteArrayOutputStream();
final byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8);
}