Java中如何讀取和寫入zip文件問題
Java讀取和寫入zip文件
在我們?nèi)粘J褂弥?,zip壓縮文件是非常常用的,市面上也有許多壓縮軟件,那么我們?yōu)槭裁匆胘ava去操作zip,使用壓縮軟件不香嗎?
其實試想有這樣一個需求,在這個項目中,有上傳功能,如果要上傳多個文件,這樣頻繁的操作遠遠不如上傳一個壓縮包方便,上傳后如果要操作這些壓縮包里的文件,用IO流不就方便多了。
因此就得先了解ZipInputStream類和ZipOutputStream類。
- ZipInputStream:繼承自FilterInputStream類,采用了裝飾器模式,可以直接讀取zip包中的內(nèi)容, 內(nèi)部封裝有ZipEntry類型的屬性,在讀取zip文件內(nèi)部子文件時,調(diào)用getNextEntry()方法時,每個ZipEntry對象就是每個子文件。
- ZipOutputStream:繼承自FilterOutputStream類,采用了裝飾器模式,可以直接寫入內(nèi)容到zip包中, 內(nèi)部同樣封裝有ZipEntry類型的屬性,但是在寫入Zip壓縮文件時,調(diào)用putNextEntry()方法,需要把每個子文件作為ZipEntry對象傳入。
讀取Zip包(解壓縮)
首先要創(chuàng)建解壓縮目錄targetDir,通常是與zip文件在同一個目錄下,通過用zip文件的父目錄與zip文件的文件名作為數(shù)據(jù)源,并調(diào)用mkdir()方法創(chuàng)建目錄。
第二步就是解析并讀取zip壓縮文件,創(chuàng)建一個ZipInputStream,傳入一個FileInputStream作為數(shù)據(jù)源,然后循環(huán)調(diào)用getNextEntry(),遍歷zip文件每個子文件,每次循環(huán)獲取子文件的文件名并創(chuàng)建該文件的輸出流,調(diào)用write()方法,讀取文件內(nèi)容并寫入輸出流。
代碼如下:
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class Demo01 { public static void main(String[] args) { // 要進行解壓縮的zip文件 File zipFile = new File("D:\\test\\1-201023201325.zip"); // 1.創(chuàng)建解壓縮目錄 // 獲取zip文件的名稱 String zipFileName = zipFile.getName(); // 根據(jù)zip文件名稱,提取壓縮文件目錄 String targetDirName = zipFileName.substring(0, zipFileName.indexOf(".")); // 創(chuàng)建解壓縮目錄 File targetDir = new File(zipFile.getParent() + "\\" + targetDirName); if (!targetDir.exists()) { targetDir.mkdir(); // 創(chuàng)建目錄 } // 2.解析讀取zip文件 try (ZipInputStream in = new ZipInputStream(new FileInputStream(zipFile), Charset.forName("gbk"))) { // 遍歷zip文件中的每個子文件 ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) { // 獲取zip壓縮包中的子文件名稱 String zipEntryFileName = zipEntry.getName(); // 創(chuàng)建該文件的輸出流 String zipFilePath = targetDir.getPath() + "\\" + zipEntryFileName; // 輸出流定義在try()塊,結(jié)束自動清空緩沖區(qū)并關(guān)閉 try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(zipFilePath))) { // 讀取該子文件的字節(jié)內(nèi)容 byte[] buff = new byte[1024]; int len = -1; while ((len = in.read(buff)) != -1) { bos.write(buff, 0, len); } } } } catch (IOException e) { e.printStackTrace(); } } }
寫入zip包(壓縮)
首先創(chuàng)建File對象rootDir引用原始目錄,然后創(chuàng)建一個ZipOutputStream,傳入一FileOutputStream作為數(shù)據(jù)源,調(diào)用listFiles()方法,獲取并遍歷原始目錄下的子文件列表,每次循環(huán)創(chuàng)建一個ZipEntry,每寫入一個文件前,調(diào)用putNextEntry()方法,然后將原文件的字節(jié)內(nèi)容,寫入zip壓縮包,需要注意,每次寫完文件,必須調(diào)用closeEntry()結(jié)束當(dāng)前ZipEntry。
代碼如下:
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Demo02 { public static void main(String[] args) { // 原始目錄 File rootDir = new File("D:\\test\\20220529"); System.out.println(rootDir.getAbsolutePath()); // 將原始目錄中的文件,“寫入”zip壓縮文件 try (ZipOutputStream out = new ZipOutputStream( new FileOutputStream(rootDir.getParent() + "\\" + rootDir.getName() + ".zip"))) { // 獲取并遍歷原始目錄下的子文件列表 File[] files = rootDir.listFiles(); for (File f : files) { // 創(chuàng)建一個ZipEntry out.putNextEntry(new ZipEntry(f.getName())); // 將原文件的字節(jié)內(nèi)容,寫入zip壓縮包 out.write(Files.readAllBytes(f.toPath())); // 結(jié)束當(dāng)前ZipEntry out.closeEntry(); } } catch (IOException e) { e.printStackTrace(); } } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Java LinkedHashMap與HashMap的使用
這篇文章主要通過幾個示例為大家詳細介紹了Java中LinkedHashMap與HashMap的常見使用和概述,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-10-10Java連接MySQL8.0 JDBC的詳細步驟(IDEA版本)
這篇文章主要介紹了Java連接MySQL8.0 JDBC的詳細步驟(IDEA版本),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04SpringBoot實現(xiàn)調(diào)用自定義的應(yīng)用程序((最新推薦)
這篇文章主要介紹了SpringBoot實現(xiàn)調(diào)用自定義的應(yīng)用程序的相關(guān)知識,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-06-06java rocketmq--消息的產(chǎn)生(普通消息)
這篇文章主要介紹了java rocketmq--消息的產(chǎn)生(普通消息),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下2019-06-06Spring?BeanFactory容器的構(gòu)建和使用示例詳解
BeanFactory是Spring框架中的一部分,它提供了IoC(控制反轉(zhuǎn))的實現(xiàn)機制,下面小編就來和大家簡單聊聊BeanFactory容器的構(gòu)建和使用示例吧2023-07-07