如何从可执行的Jar文件中加载xml资源文件,并将其保存到Jar所在的文件夹中



我有一个自定义的java服务器。它使用一个外部xml配置文件。我有一些命令行选项来帮助用户,通常显示帮助文件、设置端口等

我最近添加了一个命令来生成服务器的默认配置文件。这是一个xml文件。在研究了我的选项后,在jar中打包一个默认的xml文件似乎是一种方法,但我显然缺少了一些东西。到目前为止,我的代码如下:

public class ResourceLoader {
private File outFile = null;
private Reader fileReader = null;
private Writer fileWriter = null;
private InputStream is = null;
private char[] buffer = null;
public ResourceLoader() {
outFile = new File("default-server.xml");
}
public void generateDefaultServerXml() {
is = ResourceLoader.class.getResourceAsStream("/default-server.xml");
if (is == null) {
System.out.println("Configuraiton File generation failed. The InputStream is null.");
} else {
fileReader = new InputStreamReader(is);
}
buffer = new char[4096];
FileOutputStream fos;
try {
fos = new FileOutputStream(outFile);
fileWriter = new OutputStreamWriter(fos);
while (fileReader.read(buffer) != -1) {
fileWriter.write(buffer, 0, buffer.length);
fileWriter.flush();
buffer = new char[4096];
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fileReader.close();
fileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

当我在eclipse中运行上面的代码时,它运行得很好,但最初,在我导出jar文件后,当我从终端运行命令时,服务器找不到default-server.xml文件
文件本身与其他一些配置文件和上述类一起位于一个名为main.resources的包中。

此后,我将ResourceLoader.class移到了另一个包中。之后,服务器似乎在main.resources包中找到了xml文件(InputStream不是null),但生成的default-server.xml文件为空。

同样,当我在eclipse中运行它时,这一切都非常好,只有在我导出项目并尝试从终端发出命令之后,进程才会失败。我做错了什么?

上面的类被实例化,并从服务器的主方法调用generateDefaultServerXml()

编辑:我编写default-server.xml的路径有点错误。现在我已经对它进行了调整,当我在Eclipse中运行它时,代码的工作方式与预期完全一样。以正确的方式读取资源,并将其写入到正确位置的文件中。但当我从jar文件中尝试相同的东西时,它仍然不起作用。

当前行ResourceLoader.class.getResourceAsStream("/default-server.xml")表示您正试图从类路径的根目录加载名为default-server.xml的资源,或者更简单地说,从jar文件的根目录。这意味着xml文件不应该在jar文件中的任何包中。

当你组装你的jar文件,然后在上面运行jar tf my.jar时,你看到你的default-server.xml文件了吗?它是在某个包中还是在jar文件的根目录中?

这里的问题是因为您将应用程序打包为jar。调用外部资源的过程完全不同。

你需要有一个文件夹结构作为

root
--your jar
--your xml file

如果应用程序在jar中使用default-server.xml文件,那么您的代码应该可以工作。否则,如果要使用external default xml file,请替换代码中的下一行。

is = new FileInputStream("./default-server.xml");

如果您想要在root位置的输出文件,请使用以下代码

public ResourceLoader() {
outFile = new File("./default-server.xml");
}

根据讨论的备用代码

public class ResourceLoader {
public void generateDefaultServerXml() {
try {
String defaultxmltext  =readFileToString("/default-server.xml");
writeFileFromInputString(defaultxmltext);
} catch (IOException e) {
//exception
}
}
public static void writeFileFromInputString(String everything) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("./default-server.xml"))) {
everything = everything.replaceAll("n", System.getProperty("line.separator"));
writer.write(everything);
}
}
public static String readFileToString(String path) throws IOException {
String everything = null;
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
everything = sb.toString();
}
return everything;
}
}

希望这能帮助

考虑一下你的文件位于src/main/resources上,试试这个

getClass().getClassLoader().getResource(fileName)

据我所知,你的主要问题是你传递了错误的路径,因为你提到xml在main.resources下。当你试图加载文件时,你需要将其添加到路径中,下面是一段适用于的示例代码

Scanner sc = null;
PrintWriter writer = null;
try {
sc = new Scanner(getClass().getResourceAsStream("main/resources/server.xml"));
writer = new PrintWriter("./default_server.xml", "UTF-8");
while(sc.hasNextLine()) {
writer.println(sc.nextLine());
}
} catch (Exception e) {
} finally {
if(sc != null) {
sc.close();
}
if(writer != null){
writer.close();
}
}

最新更新