Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream
文件壓縮 ZipOutputStream
用ZipOutputStream來(lái)壓縮一個(gè)文件夾時(shí),要搭配ZipEntry來(lái)使用。ZipEntry是用來(lái)創(chuàng)建壓縮文件的。
舉個(gè)例子,向壓縮文件中添加一個(gè)文件的代碼:
//zipOut:壓縮文件的路徑
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut));
//zipOutputStream.putNextEntry() ====> 向壓縮包中添加一個(gè)文件
//new ZipEntry("text1.txt") ======? zip壓縮包中文件都是用ZipEntry對(duì)象,
//"text1.txt"===》是文件在壓縮文件的路徑,text1.txt表示在壓縮文件的根路徑
zipOutputStream.putNextEntry(new ZipEntry("text1.txt"));
如下圖:

在創(chuàng)建ZipEntry對(duì)象時(shí)可以指定文件在壓縮包的位置:new ZipEntry(“second-dir\second-01.txt”)

在使用ZipOutputStream壓縮文件時(shí)要注意的地方就是這些,下面給一個(gè)壓縮文件的代碼:
static final int BUFFER_SIZE = 4 << 10;
/**
* 壓縮指定目錄下的所有文件
* @param dir 指定壓縮目錄
* @param destZipName 指定壓縮包名字
*/
public void zip(String dir,String zipPath,String destZipName) throws IOException {
File file = new File(dir);
/**1.為zip文件創(chuàng)建目錄*****/
String path = file.getParentFile().getAbsolutePath();
if(isNull(destZipName))destZipName = file.getName()+".zip";
if(isNull(zipPath)) zipPath = path;
String zipOut = zipPath + File.separator + destZipName;
File zipOutFile = new File(zipOut);
if(!zipOutFile.getParentFile().exists()){
zipOutFile.getParentFile().mkdirs();
}
/**為zip文件創(chuàng)建目錄*****/
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut));
if(!file.isDirectory())zipOutputStream.close();
File[] subFiles = file.listFiles();
for (File subFile : subFiles) {
buildZipDir(zipOutputStream,subFile,null);
}
zipOutputStream.close();
}
void buildZipDir(ZipOutputStream zipOut,File file,String baseDir) throws IOException {
if(file.isFile()){
String zipEntryName = baseDir == null ? file.getName() : baseDir+File.separator+file.getName();
zipOut.putNextEntry(new ZipEntry(zipEntryName));
byte[] buffer = new byte[BUFFER_SIZE];
try(InputStream inputStream = new FileInputStream(file)){
int len = -1;
while((len = inputStream.read(buffer)) != -1){
zipOut.write(buffer,0,len);
}
zipOut.flush();
zipOut.closeEntry();
}
}
else{//文件是dir,繼續(xù)遞歸找文件
File[] subFiles = file.listFiles();
if(subFiles.length ==0){//處理空文件夾
String zipName = baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ;
zipOut.putNextEntry(new ZipEntry(zipName));
zipOut.closeEntry();
}else{
for (File subFile : subFiles) {
String subBaseDir =baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ;
buildZipDir(zipOut,subFile,subBaseDir);
}
}
}
}
public boolean isNull(String str){
return str == null || str.equals("");
}測(cè)試:
@Test
public void testZip() throws IOException {
String dir = "D:\\test-zip";
//dir : 要壓縮的目錄
//D:\\yy\\ 指定壓縮文件的位置
//path-test.zip 指定壓縮文件的名字
zip(dir,"D:\\yy\\","path-test.zip");
}
文件解壓:ZipInputStream
ZipInputStream讀取壓縮文件,配合ZipFile使用;通過(guò)上面的例子,我們知道壓縮包里的是一個(gè)個(gè)ZipEntry對(duì)象,在解壓時(shí),可以遍歷壓縮包獲取到ZipEntry對(duì)象。每一個(gè)ZipEntry對(duì)象都是一個(gè)文件,使用ZipFile可以獲取到每一個(gè)ZipEntry對(duì)象的文件流;獲取到文件流就可以將壓縮包的文件讀出來(lái)了。
public void unZip(String zipPath,String unzipPath) throws IOException {
File file = new File(zipPath);
ZipFile zipFile = new ZipFile(file);//zip文件
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
if(isNull(unzipPath))unzipPath = zipPath.replace(".zip","");
ZipEntry nextEntry = null;
while( (nextEntry = zipInputStream.getNextEntry()) != null){
String name = nextEntry.getName();
String fileOutPath = unzipPath + File.separator + name;
File fileOut = new File(fileOutPath);
if(!fileOut.getParentFile().exists()){
fileOut.getParentFile().mkdirs();
}
if(!fileOut.exists()){
fileOut.createNewFile();
}
OutputStream output = new FileOutputStream(fileOutPath);
InputStream inputStream = zipFile.getInputStream(nextEntry);//通過(guò)ZipFile獲取到ZipEntry的文件流
int read = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while((read = inputStream.read(buffer) ) != -1){
output.write(buffer,0, read);
}
output.flush();
output.close();
inputStream.close();
}
zipInputStream.close();
zipFile.close();
}測(cè)試:
public void testUnzip() throws IOException {
String zip = "D:\\yy\\path-test.zip";
unZip(zip,null);
}
總結(jié)
到此這篇關(guān)于Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream的文章就介紹到這了,更多相關(guān)Java zip文件壓縮解壓內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull)
這篇文章主要介紹了Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull),數(shù)據(jù)庫(kù)的字段命名方式為使用下劃線連接,對(duì)應(yīng)的實(shí)體類(lèi)應(yīng)該是駝峰命名方式,而我使用的是和數(shù)據(jù)庫(kù)同樣的命名方式,需要的朋友可以參考下2022-01-01
Spring延遲Bean初始化的實(shí)現(xiàn)示例
延遲初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用時(shí)才創(chuàng)建及初始化Bean,本文主要介紹了Spring延遲Bean初始化的實(shí)現(xiàn)示例,感興趣的可以了解一下2024-06-06
Mybatis-plus使用TableNameHandler分表詳解(附完整示例源碼)
這篇文章主要介紹了Mybatis-plus使用TableNameHandler分表詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
這一次搞懂Spring代理創(chuàng)建及AOP鏈?zhǔn)秸{(diào)用過(guò)程操作
這篇文章主要介紹了這一次搞懂Spring代理創(chuàng)建及AOP鏈?zhǔn)秸{(diào)用過(guò)程操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
IDEA生成servlet程序的實(shí)現(xiàn)步驟
這篇文章主要介紹了IDEA生成servlet程序的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Java中YYYY-MM-dd與yyyy-MM-dd的區(qū)別及跨年問(wèn)題
YYYY-MM-dd可能會(huì)導(dǎo)致跨年周的日期被歸屬到錯(cuò)誤的年份, yyyy-MM-dd總是表示實(shí)際的日歷年份,無(wú)論日期所在的周是否跨年,本文就來(lái)介紹一下兩者的區(qū)別,感興趣的可以了解一下2024-01-01

