1. 程式人生 > >java 讀取jar包中的檔案

java 讀取jar包中的檔案

參考: https://blog.csdn.net/rchm8519/article/details/39557499

參考: https://www.cnblogs.com/zeciiii/p/4178824.html

 需求:

我自己寫了一個Java 的記事本工具,然後實現快捷鍵功能,於是就把快捷鍵對應的key-value 儲存到properties檔案中,

類似:

Ctrl,S=\u4FDD\u5B58
Ctrl,P=\u53E6\u5B58\u4E3A
Ctrl,N=\u65B0\u5EFA
Ctrl,Esc=\u9000\u51FA

問題:

但是發現,當將專案打成jar 包以後,在jar 包內部讀取jar包內部的檔案,一直都行不通,因為路徑問題,從外部讀取jar包中的內容,可以通過: ...jar!/檔案路徑,找到內容,但是自己本身讀取自己,就會總是FileNotFoundException ,後來發現有個專門讀取jar包內容的JarFile

從外部讀取jar包內容例項:

public static Map<String, String> init(String defaultPath) {
		if(CheckUtil.empty(defaultPath)){
			defaultPath = ReadProperties.defaultPath;
		}
		String packagePath = "/file/"+defaultPath;
		URL resource = ReadProperties.class.getResource(packagePath);//根據 source 檔案下的包路徑,得到url,必須是絕對路徑
		String path = resource.getFile();//根據url 得到完整的 路徑
		PropertiesParse parse = new PropertiesParse();
		InputStream input = null;
		if(path.contains(".jar")) {
			//得到jar目錄
			String jarPath = path.substring(0, path.indexOf("!"));
			//得到jarFile 物件
			JarFile jarFile = null;
			try {
				jarFile = new JarFile(jarPath);
			} catch (IOException e) {
				e.printStackTrace();
			}
			ZipEntry entry = jarFile.getEntry(packagePath.substring(1));//這裡是相對路徑,前面沒有斜槓/
			try {
				input = jarFile.getInputStream(entry);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}else{//正常class 讀取,普通File 讀取
			try {
				input = new FileInputStream(new File(path));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		parse.setSrcToReader(input);
		Map<String, String> map = parse.getMap();
		
		return map;
	}
	
	public static void main(String[] args) {
		String defaultPath = "";
		String packagePath = "/file/"+"keyEvent.properties";
		// 讀取jar包中的檔案,參考地址; https://blog.csdn.net/rchm8519/article/details/39557499,https://www.cnblogs.com/zeciiii/p/4178824.html
		String str = "/C:/Users/12198/Desktop/KEditPad.jar";// /file/keyEvent.properties
		JarFile jarFile = null;
		PropertiesParse parse = new PropertiesParse();
		InputStream input = null;
		try {
			jarFile = new JarFile(str);//通過jarFile  讀取jar包
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//遍歷entry 物件
		Enumeration<JarEntry> entries = jarFile.entries();
		while(entries.hasMoreElements()){
			System.out.println(entries.nextElement().getName());
		}
		ZipEntry entry = jarFile.getEntry(packagePath.substring(1));//name 最開頭沒有/,換句話就是相對路徑
		try {
			input = jarFile.getInputStream(entry);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		parse.setSrcToReader(input);
		Map<String, String> map = parse.getMap();
		
		
	}
	

得到了檔案路徑,通過File 的new File(str),會報FileNotFound 異常,java 讀取jar包中的檔案,應該用JarFile 類來讀取

 

jar包內部讀取jar包內容例項:(外部或者專案中也可通過此方式)

如果file放在原始碼目錄(例如:我把檔案放在src下的file包下)下,則無論是在外部讀取還是在jar包中讀取,都可通過classLoader

public static Map<String, String> init(String defaultPath) {
		 InputStream stream =  
                 ClassLoader.getSystemResourceAsStream("file/keyEvent.properties");
		 PropertiesParse parse = new PropertiesParse();
		 parse.setSrcToReader(stream);
			Map<String, String> map = parse.getMap();
		return map;
		
	}