Java中實(shí)現(xiàn)將jar包內(nèi)文件資源釋放出來(lái)
Java將jar包內(nèi)文件資源釋放出來(lái)
有些時(shí)候我們需要讀取并釋放jar包內(nèi)文件到j(luò)ar包外。這樣其實(shí)很簡(jiǎn)單,使用InputStream和OutputStream即可。
文件在jar包中時(shí),一般是先讀取他們,再輸出。以我這里為例:
可以看到我這里的代碼文件目錄結(jié)構(gòu),代碼文件夾根目錄下有一個(gè)a.txt,還有一個(gè)test文件夾,其中有一個(gè)Test類和b.txt,sda.pdf。
打包為jar后結(jié)構(gòu)不變,如下:
現(xiàn)在演示文件輸出,把jar包內(nèi)的test文件夾里面的那個(gè)sda.pdf輸出,代碼如下:
InputStream is = Test.class.getResourceAsStream("sda.pdf");// 流式讀取jar包內(nèi)文件,使用classpath File f = new File("E:\\中轉(zhuǎn)\\tio\\a\\out.pdf");// 指定輸出文件 File fp = new File(f.getParent());// 輸出文件的父目錄 if (!fp.exists()) {// 父目錄不存在時(shí)先創(chuàng)建 fp.mkdirs(); } if (!f.exists()) {// 文件不存在時(shí)先創(chuàng)建 f.createNewFile(); } OutputStream os = new FileOutputStream(f);// 創(chuàng)建輸出流 int index = 0;// 當(dāng)前讀取的位數(shù) byte[] bytes = new byte[1024];// 指定每次讀取的位數(shù),這里以1024為例 // 開(kāi)始讀取文件,一遍讀取一邊輸出文件。每次讀取1024的長(zhǎng)度并儲(chǔ)存于bytes這個(gè)數(shù)組中,然后寫(xiě)入至目標(biāo)文件 while ((index = is.read(bytes)) != -1) { os.write(bytes, 0, index);// 輸出文件,write()方法參數(shù)分別為:寫(xiě)入的數(shù)據(jù)、開(kāi)始寫(xiě)入的位置(0為從開(kāi)頭寫(xiě)入),寫(xiě)入長(zhǎng)度 } // 關(guān)閉流并保存文件 os.flush(); os.close(); is.close();
這里要說(shuō)明的重點(diǎn)是
InputStream is = Test.class.getResourceAsStream("sda.pdf");
這就是流式讀取文件,其語(yǔ)法是:
InputStream is = 類名.class.getResourceAsStream("文件路徑");
這里因?yàn)槭亲x取jar內(nèi)的文件,所以路徑用classpath方式表示。上面的Test.class.getResourceAsStream()就是以Test這個(gè)類的位置為出發(fā)點(diǎn)。括號(hào)里面的參數(shù)就是在jar包中,以Test類為準(zhǔn)的相對(duì)路徑。
當(dāng)然也可以使用絕對(duì)路徑。文件路徑以"/"開(kāi)頭的就是絕對(duì)路徑,絕對(duì)路徑不再是以類為出發(fā)點(diǎn),/就代表jar包的根目錄。
舉個(gè)例子:
如果要讀取上述jar包內(nèi)根目錄下的a.txt,那就要這樣寫(xiě):
InputStream is = Test.class.getResourceAsStream("/a.txt");
這時(shí)就是以絕對(duì)路徑方式找到文件。雖然指定了Test.class,但是因?yàn)槭墙^對(duì)路徑,路徑就與Test類無(wú)關(guān)了。
jar包的動(dòng)態(tài)加載和釋放
import sun.misc.ClassLoaderUtil; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; /** * java jar的動(dòng)態(tài)加載和釋放 */ public class TestMain { public static void main(String[] args) throws MalformedURLException, Exception { System.out.println(new File(".").getAbsolutePath()); URLClassLoader urlClassLoader=new URLClassLoader(new URL[]{new URL("file:C:\\Users\\Administrator\\IdeaProjects\\test\\data.jar")}); Class classStudentServiceImpl= urlClassLoader.loadClass("StudentServiceImpl"); Method method= classStudentServiceImpl.getMethod("getName",new Class[]{}); Constructor localConstructor = classStudentServiceImpl.getConstructor(new Class[] {}); Object instance = localConstructor.newInstance(new Object[] {}); Object ret= method.invoke(instance); System.out.println(ret); ClassLoaderUtil.releaseLoader(urlClassLoader); while(true) { Thread.sleep(1000); System.out.println("run"); } } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)熱部署Community的示例代碼
本文主要介紹了SpringBoot實(shí)現(xiàn)熱部署Community的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06基于controller使用map接收參數(shù)的注意事項(xiàng)
這篇文章主要介紹了基于controller使用map接收參數(shù)的注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10使用Java servlet實(shí)現(xiàn)自動(dòng)登錄退出功能
這篇文章主要介紹了使用Java servlet實(shí)現(xiàn)自動(dòng)登錄退出功能,,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11解決spring-integration-mqtt頻繁報(bào)Lost connection錯(cuò)誤問(wèn)題
這篇文章主要介紹了解決spring-integration-mqtt頻繁報(bào)Lost connection錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Java基礎(chǔ)之引用相關(guān)知識(shí)總結(jié)
今天聊聊Java的引用,大多數(shù)時(shí)候我們說(shuō)引用都是強(qiáng)引用,只有在對(duì)象不使用的情況下才會(huì)釋放內(nèi)存,其實(shí)Java 內(nèi)存有四種不同的引用.一起看看吧,,需要的朋友可以參考下2021-05-05