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

时间:2016-05-24 08:36:03

标签: java eclipse embedded-resource

我有一个自定义的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中运行它时,这一切都非常有效,只有在我导出项目并尝试从终端发出进程失败的命令之后。我究竟做错了什么?

实例化上述类,并从服务器的main方法调用generateDefaultServerXml()

编辑:我写default-server.xml的路径有些错误。现在我调整了它,当我在Eclipse中运行它时,代码的工作方式完全符合预期。以正确的方式读取资源,并将文件写入正确的位置。但是当我从jar文件中尝试相同的东西时它仍然无效。

4 个答案:

答案 0 :(得分:1)

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

您需要将文件夹结构设为

sample()

如果应用程序在jar中使用root --your jar --your xml file 文件,您的代码将起作用。 否则,如果要使用default-server.xml,请在代码中替换以下行。

external default xml file

如果您希望 is = new FileInputStream("./default-server.xml"); 位置的输出文件使用以下代码

root

根据讨论的替代代码

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

希望这有帮助

答案 1 :(得分:1)

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

组装jar文件然后在其上运行jar tf my.jar时,是否看到了default-server.xml文件?它是驻留在某个包中还是存放在jar文件的根目录中?

答案 2 :(得分:1)

考虑位于src / main / resources上的文件试试这个

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

答案 3 :(得分:1)

就我所知,你的主要问题是你传递了错误的路径,因为你提到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();
      }
   }