Java中實(shí)現(xiàn)將jar包內(nèi)文件資源釋放出來
Java將jar包內(nèi)文件資源釋放出來
有些時(shí)候我們需要讀取并釋放jar包內(nèi)文件到j(luò)ar包外。這樣其實(shí)很簡單,使用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為例
// 開始讀取文件,一遍讀取一邊輸出文件。每次讀取1024的長度并儲存于bytes這個(gè)數(shù)組中,然后寫入至目標(biāo)文件
while ((index = is.read(bytes)) != -1) {
os.write(bytes, 0, index);// 輸出文件,write()方法參數(shù)分別為:寫入的數(shù)據(jù)、開始寫入的位置(0為從開頭寫入),寫入長度
}
// 關(guān)閉流并保存文件
os.flush();
os.close();
is.close();這里要說明的重點(diǎn)是
InputStream is = Test.class.getResourceAsStream("sda.pdf");這就是流式讀取文件,其語法是:
InputStream is = 類名.class.getResourceAsStream("文件路徑");這里因?yàn)槭亲x取jar內(nèi)的文件,所以路徑用classpath方式表示。上面的Test.class.getResourceAsStream()就是以Test這個(gè)類的位置為出發(fā)點(diǎn)。括號里面的參數(shù)就是在jar包中,以Test類為準(zhǔn)的相對路徑。
當(dāng)然也可以使用絕對路徑。文件路徑以"/"開頭的就是絕對路徑,絕對路徑不再是以類為出發(fā)點(diǎn),/就代表jar包的根目錄。
舉個(gè)例子:
如果要讀取上述jar包內(nèi)根目錄下的a.txt,那就要這樣寫:
InputStream is = Test.class.getResourceAsStream("/a.txt");這時(shí)就是以絕對路徑方式找到文件。雖然指定了Test.class,但是因?yàn)槭墙^對路徑,路徑就與Test類無關(guān)了。
jar包的動態(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的動態(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)文章
Spring的異常重試框架Spring Retry簡單配置操作
這篇文章主要介紹了Spring的異常重試框架Spring Retry簡單配置操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Spring Data Jpa 復(fù)合主鍵的實(shí)現(xiàn)
這篇文章主要介紹了Spring Data Jpa 復(fù)合主鍵的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
MyBatis學(xué)習(xí)教程(二)—如何使用MyBatis對users表執(zhí)行CRUD操作
這篇文章主要介紹了MyBatis學(xué)習(xí)教程(二)—如何使用MyBatis對users表執(zhí)行CRUD操作的相關(guān)資料,需要的朋友可以參考下2016-05-05
new出來的對象中無法使用@autowired進(jìn)行對象bean注入問題
這篇文章主要介紹了基于new出來的對象中無法使用@autowired進(jìn)行對象bean注入問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
SpringBoot請求參數(shù)傳遞與接收說明小結(jié)
這篇文章主要介紹了SpringBoot請求參數(shù)傳遞與接收,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12
使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程
這篇文章主要介紹了使用迭代器模式來進(jìn)行Java的設(shè)計(jì)模式編程,文中對迭代器模式中的容器封裝方面的知識進(jìn)行了講解,需要的朋友可以參考下2016-02-02

