如何讀取jar包中的檔案
阿新 • • 發佈:2020-09-03
1.getResource
//當前類檔案為根目錄,取其子目錄x下的y檔案 Main.class.getResource("x/y") //當前類檔案的根目錄為根目錄,取其子目錄x下的y檔案 Main.class.getResource("/x/y")
上面的解釋有點拗口,其實就是路徑不以斜線開頭,表示從當前class檔案為根目錄,然後找檔案,路徑以斜線開頭,則從當前class的檔案的根目錄,比如當前class如果有包限定的話,那就是從包的最頂層,作為根目錄,來載入檔案。
2.getResourceAsStream
private static String readFile(String file) throws IOException { InputStream input= null; BufferedInputStream bis = null; StringBuilder sb = new StringBuilder(); try { input = Main.class.getResourceAsStream(file); bis = new BufferedInputStream(input); byte[] temp = new byte[1024]; int len; while ((len = bis.read(temp)) != -1) { sb.append(new String(temp, 0, len, StandardCharsets.UTF_8)); } } finally { if (bis != null) { bis.close(); } if (input != null) { input.close(); } } return sb.toString(); }
這裡要注意的是,上面的寫法中是Main.class.getResourceAsStream(file),即從當前類的範圍內去找file,
如果寫成Main.class.getClassLoader().getResourceAsStream(file),則有可能找不到檔案,因為已經從載入器的可見範圍去找檔案了。
3.JarFile
private static String readFile(String file) throws IOException { String jarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath(); InputStream input = null; BufferedInputStream bis = null; StringBuilder sb = new StringBuilder(); try { JarFile jarFile = new JarFile(jarPath); ZipEntry zipEntry = jarFile.getEntry(file); //can not find the deserved file if (zipEntry == null) { logger.info("Can not find file {} in {}", file, jarPath); return null; } input = jarFile.getInputStream(zipEntry); bis = new BufferedInputStream(input); byte[] temp = new byte[1024]; int len; while ((len = bis.read(temp)) != -1) { sb.append(new String(temp, 0, len, StandardCharsets.UTF_8)); } } catch (IOException ex) { logger.error("Fail to read file {}:{}", file, ex.getMessage()); logger.error("Exception:", ex); throw new RuntimeException("A valid file " + file + " is unavailable."); } finally { if (bis != null) { bis.close(); } if (input != null) { input.close(); } } return sb.toString(); }
上面這種方式,通過jar包的方式來載入檔案,通用性更強一些,在前述兩種都不可用的時候,往往還是可用的。