簡體   English   中英

如何從可執行的Jar文件中加載xml資源文件並將其保存到jar所在的文件夾中?

[英]How can I load an xml resource file from within an executible Jar file and save it to the folder the jar is located in?

我有一個自定義的Java服務器。 它使用一個外部xml配置文件。 我有一些命令行選項可以幫助用戶,還有顯示幫助文件,設置端口等常用的東西。

我最近添加了一個命令來為服務器生成默認配置文件。 這是一個xml文件。 在研究了我的選項之后,將默認的xml文件打包到jar中似乎是可行的方法,但是我顯然缺少了一些東西。 到目前為止,我的代碼如下所示:

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 main.resources文件為空。

同樣,當我在eclipse中運行它時,這一切都很好,只有在導出項目並嘗試從終端發出命令后,該過程才會失敗。 我究竟做錯了什么?

從服務器的主方法實例化上述類,並調用generateDefaultServerXml()

編輯:我編寫default-server.xml路徑略有錯誤。 現在,我已經對其進行了調整,因此代碼在Eclipse中運行時可以按預期完全正常工作。 以正確的方式讀取資源,並在正確的位置將其寫入文件。 但是,當我從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;
    }
}

希望這可以幫助

當前行ResourceLoader.class.getResourceAsStream("/default-server.xml")表示您正在嘗試從類路徑的根目錄(或更簡單地說,從jar的根目錄)加載名為default-server.xml的資源。文件。 這意味着xml文件不應放在jar文件內的任何包中。

當您匯編jar文件並在其上運行jar tf my.jar時,您是否看到default-server.xml文件? 它駐留在某個包中還是在jar文件的根目錄中?

考慮您的文件位於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();
      }
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM