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

在創(chuàng)建ZipEntry對象時(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("");
}測試:
@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使用;通過上面的例子,我們知道壓縮包里的是一個(gè)個(gè)ZipEntry對象,在解壓時(shí),可以遍歷壓縮包獲取到ZipEntry對象。每一個(gè)ZipEntry對象都是一個(gè)文件,使用ZipFile可以獲取到每一個(gè)ZipEntry對象的文件流;獲取到文件流就可以將壓縮包的文件讀出來了。
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);//通過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();
}測試:
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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
老生常談Java中instanceof關(guān)鍵字的理解
java 中的instanceof 運(yùn)算符是用來在運(yùn)行時(shí)指出對象是否是特定類的一個(gè)實(shí)例。這篇文章主要介紹了老生常談Java中instanceof關(guān)鍵字的理解,需要的朋友可以參考下2018-10-10
java返回前端樹形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式
近期項(xiàng)目有個(gè)需求,需要將組織機(jī)構(gòu)數(shù)據(jù)拼成樹型結(jié)構(gòu)返回至前端,下面這篇文章主要給大家介紹了關(guān)于java返回前端樹形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05
J2SE基礎(chǔ)之在Eclipse中運(yùn)行hello world
本文的內(nèi)容非常的簡單,跟隨世界潮流,第一個(gè)Java程序輸出“Hell World!”。希望大家能夠喜歡2016-05-05
Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐
最近的一個(gè)項(xiàng)目中涉及到了支付業(yè)務(wù),其中用到了微信支付和支付寶支付,本文就來介紹一下Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10

