java讀取zip/jar包中文件的幾種方式
1、jar vs zip:
jar 文件和 zip 文件都是歸檔文件,并且都經(jīng)過壓縮。事實上,jar 文件使用與 zip 文件相同的存檔和壓縮技術,所以 jar 文件實際上是一種特定類型的 zip 文件。(JAR 文件本質上是一個包含可選 META-INF 目錄的 zip 文件。)這一切都意味著:
- 您可以使用與打開 zip 文件相同的工具打開 jar 文件
- jar 文件是 zip 文件的子集,因此如果 zip 文件遵循 jar 規(guī)范,則它可以用作 jar 文件
2、讀取zip壓縮文件:
1)方法一:通過ZipFile從文件中讀取
private static void readZipFile() {
try (ZipFile zipFile = new ZipFile("/data/testzip.zip");) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
System.out.println("fileName:"+entry.getName()); //文件名
InputStream stream = zipFile.getInputStream(entry); //讀取文件內容
read(stream);
}
} catch(Exception e) {}
//zipFile.close();
}
private static void read(InputStream in) {
try (InputStreamReader reader = new InputStreamReader(in, "UTF-8");
BufferedReader br = new BufferedReader(reader);) {
String con = null;
while ((con = br.readLine()) != null) {
System.out.println(con);
}
} catch (Exception e) {}
}2)方法二:通過ZipInputStream從流中讀取
private static InputStream getInputStream() throws FileNotFoundException {
File file = new File("/data/testzip.zip");
InputStream in = new FileInputStream(file);
return in;
}
//錯誤方法
private static void readZipInputStream() throws FileNotFoundException, IOException {
InputStream zippedIn = getInputStream(); // zip壓縮文件流
ZipInputStream zis = new ZipInputStream(zippedIn);
read(zis); //讀取的是空
}
//正確方法
private static void readZipInputStream2() throws FileNotFoundException, IOException {
InputStream zipFileInput = getInputStream(); // zip壓縮文件流
ZipInputStream zis = new ZipInputStream(zipFileInput);
ZipEntry entry = null;
try {
while ((entry = zis.getNextEntry()) != null) {
try {
final String name = entry.getName();
System.out.println("fileName:"+name);
String content = IOUtils.toString(zis);
System.out.println(content);
} finally {
zis.closeEntry(); // 關閉zipEntry
}
}
} finally {
zis.close(); //關閉zipInputStream
}
}注意:在從流中讀取數(shù)據(jù)是使用了IOUtils,原因是自定義read方法讀取完后會把傳遞進來的inputStream給關閉了。如果zip包中有多個文件,那么在讀取第二個entry文件時就會報錯。zipInputStream只能在最后關閉。而IOUtils使用了copy的方式,不會關閉傳入的流。
3、jar中文件/目錄便利,以及讀?。?/h2>
1)方法一:使用JarFile讀取Jar文件
和ZipFile類似,使用'getEntry(String name)'或'entires'獲得ZipEntry或JarEntry(它們可以看作同一東西),接下來使用" JarFile.getInputStream(ZipEntry ze)"將其用于獲取InputStream
static void test1() {
String path = "/Users/liuxiao/maven-rep/org/apache/thrift/libthrift/0.9.0/libthrift-0.9.0.jar";
try (JarFile jarFile = new JarFile(new File(path));) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
if (!entry.isDirectory() && entryName.equals("org/apache/thrift/TBase.java")) {
System.out.println(entryName);// org/apache/thrift/EncodingUtils.class
read(jarFile.getInputStream(entry));
}
}
} catch (Exception e) {
}
//使用stream api
try (Stream<JarEntry> stream = new JarFile(new File(path)).stream();) {
stream
.filter(entry -> !entry.isDirectory() && entry.getName().endsWith(".class"))
.forEach(entry -> System.out.println(entry.getName()));
} catch(Exception e) {
}
}2)方法二:通過JarInputStream從流中讀取(和ZipInputStream類似)
private static InputStream getJarFileInputStream() throws FileNotFoundException {
File file = new File("/data/mvn_repo/commons-lang/commons-lang/2.1/commons-lang-2.1.jar");
InputStream in = new FileInputStream(file);
return in;
}
private static void readJarInputStream2() throws FileNotFoundException, IOException {
InputStream zipFileInput = getJarFileInputStream(); // jar包流
JarInputStream jis = new JarInputStream(zipFileInput);
JarEntry entry = null;
try {
while ((entry = jis.getNextJarEntry()) != null) {
try {
if (entry.isDirectory()) {
continue;
}
final String name = entry.getName();
System.out.println("fileName:"+name);
String content = IOUtils.toString(jis);
System.out.println(content);
} finally {
jis.closeEntry(); // 關閉zipEntry
}
}
} finally {
jis.close(); //關閉zipInputStream
}
}3)方法三:通過JarURLConnection來打開一個jar中的資源,然后通過流來讀取
static void test2() throws Exception {
String filePath = "/Users/liuxiao/maven-rep/org/apache/thrift/libthrift/0.9.0/libthrift-0.9.0.jar";
String name = "org/apache/thrift/TBase.java";
URL url = new URL("jar:file:" + filePath + "!/" + name);
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
try (InputStream in = jarConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));) {
String con = null;
while ((con = br.readLine()) != null) {
System.out.println(con);
}
} catch (Exception e) {
e.printStackTrace();
}
}總結:
由于zip和jar結構時一致的,所以ZipFile和JarFile,ZipInputStream和JarInputStream的使用方法是一樣的。需要說明的一點是,由于zip包的這種特殊結構,默認ZipInputStream中是不包含數(shù)據(jù)的,只有在調用getNextEntry方法后,才回把對應的entry(zip包中的一個文件)內容寫入到ZipInputStream中。上面的一個錯誤寫法中,可以看到直接從ZipInputStream中讀不到數(shù)據(jù),只有調用getNextEntry后才可以。
到此這篇關于java讀取zip/jar包中文件的幾種方式的文章就介紹到這了,更多相關java讀取zip/jar包文件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot中Reactor模型的基本概念和最佳實踐
Reactor模型是一種基于事件驅動和非阻塞IO的編程模型,用于處理并發(fā)和異步操作,本文將介紹Spring Boot中使用Reactor模型的基本概念和最佳實踐,幫助讀者更好地理解如何利用這一強大的工具來構建現(xiàn)代化的Java應用程序,感興趣的朋友跟隨小編一起看看吧2024-05-05
利用Spring Boot創(chuàng)建docker image的完整步驟
這篇文章主要給大家介紹了關于如何利用Spring Boot創(chuàng)建docker image的完整步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
spring注解 @PropertySource配置數(shù)據(jù)源全流程
這篇文章主要介紹了spring注解 @PropertySource配置數(shù)據(jù)源全流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Java 并發(fā)編程之ThreadLocal詳解及實例
這篇文章主要介紹了Java 并發(fā)編程之ThreadLocal詳解及實例的相關資料,需要的朋友可以參考下2017-02-02
Springboot結合@validated優(yōu)化代碼驗證
這篇文章主要介紹了Springboot與@validated注解結合從而實現(xiàn)讓你的代碼驗證更清爽,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08
springboot使用filter獲取自定義請求頭的實現(xiàn)代碼
這篇文章主要介紹了springboot使用filter獲取自定義請求頭的實例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05
Java實現(xiàn)京東聯(lián)盟API數(shù)據(jù)獲取功能
這篇文章介紹了Java獲取京東聯(lián)盟API數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Springboot調整接口響應返回時長詳解(解決響應超時問題)
當后端對于數(shù)據(jù)量較大的處理或是某些耗時的操作時,需要先對請求接口的請求進行響應,下面這篇文章主要給大家介紹了關于Springboot調整接口響應返回時長(解決響應超時問題)的相關資料,需要的朋友可以參考下2023-01-01

