1. 程式人生 > >有關打包成可執行jar包後引用jar包中配置檔案問題

有關打包成可執行jar包後引用jar包中配置檔案問題

一 問題由來

有時候我們做一些專案時,需要將一些配置資訊寫入配置檔案中,以供呼叫。比如說這樣:

wKiom1aLbvLQhC4eAAAVhpYSRkA317.png

如果我們需要在Demo.java中讀取config.txt這個檔案中的配置資訊,在這種工程目錄下是可以使用File來讀取的,但是打包成jar後,使用File將不能讀取到config.txt了,除非將這個配置資訊放在jar包的外面。

假如說我們用File來讀取檔案:

1 BufferedReader reader = new BufferedReader(new FileReader(new File("res/config.txt")));

工程狀態下是沒有問題的,但是打包成jar後執行報錯:

wKiom1aLby7hqUPdAABAzNiL0Uc895.png

很顯然是找不到指定的檔案,為什麼會出現這種問題呢?因為這時候整個jar檔案是一個檔案了,當然找不到jar包中的配置檔案了

我們繼續測試,在“測試0.jar”同級目錄下新建一個res資料夾,裡面放一個config.txt,繼續執行:

wKioL1aLb4Kxt_oaAAEEpSLIQBI941.png

wKiom1aLb13BJ1TrAACr7MeOdgw752.png

現在我們可以看到,程式執行的時候沒有報錯,已經可以正常的運行了

二 問題引申

有人可能想問,如果我非要將配置檔案打包進jar中,有沒有辦法可以訪問呢?答案是肯定的。使用 this.getClass().getResourceAsStream(“/config.txt”); 就可以了。完整的獲取輸入流是這樣的:

InputStream inputStream = this.getClass().getResourceAsStream("/config.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));

都得到BufferedReader了,接下來就是正常的讀檔案了

整個測試小專案的完整原始碼如下:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
 
public class Demo extends JFrame{
    private GridBagLayout gridbag;
    private GridBagConstraints constraints;
    private JPanel mainJPanel;
    private JLabel tip;
    private JScrollPane jScrollPane;
    private JTextArea content;
 
    private Font contentFont = new Font("宋體", Font.LAYOUT_NO_LIMIT_CONTEXT, 16);  //正文字型
 
    public Demo(){
        super("引用jar包中配置檔案Demo");
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        screenSize = Toolkit.getDefaultToolkit().getScreenSize();  //螢幕大小
        setPreferredSize(new Dimension(700, 300));
        int frameWidth = this.getPreferredSize().width;  //介面寬度
        int frameHeight = this.getPreferredSize().height;  //介面高度
        setSize(frameWidth,frameHeight);
        setLocation((screenSize.width - frameWidth) / 2,(screenSize.height - frameHeight) / 2);
         
        //初始化
        mainJPanel = new JPanel();
        tip = new JLabel("提示:");
        jScrollPane = new JScrollPane();
        content = new JTextArea(5,10);
         
        //佈局
        gridbag = new GridBagLayout();
        constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        mainJPanel.setLayout(gridbag);
         
        constraints.gridwidth = 0;  
        constraints.gridheight = 1;
        constraints.weightx = 1;  
        constraints.weighty = 0;  
        gridbag.setConstraints(tip, constraints);
        tip.setFont(contentFont);
        mainJPanel.add(tip);
         
        constraints.gridwidth = 0;  
        constraints.gridheight = 1;
        constraints.weightx = 1;  
        constraints.weighty = 1;  
        gridbag.setConstraints(jScrollPane, constraints);
        jScrollPane.setFont(contentFont);
        mainJPanel.add(jScrollPane);
         
        content.setFont(contentFont);
        jScrollPane.setViewportView(content);
        content.setLineWrap(true);
        content.setWrapStyleWord(true);
         
        try {
            InputStream inputStream = this.getClass().getResourceAsStream("/config.txt");
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
            String line = "";
            while((line = reader.readLine()) != null){
                content.append(line + "\n");
            }
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
         
        add(mainJPanel);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
     
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Demo();           
            }
        });
    }
 
}


res/config.txt:

test text

注:

這種方式雖然實現了對jar包中檔案的讀取,但是仍然是有一定弊端性的,那就是沒法在程式執行的過程中動態地修改該配置檔案中的值。