1. 程式人生 > >java 將資料夾壓縮為zip壓縮檔案

java 將資料夾壓縮為zip壓縮檔案

還記得壓縮檔案是我剛入職時,師傅讓我完成的案例,當時把我愁的哦。剛才用到,才發現忘得差不多了。哎,都是不長回頭惹的禍啊。回頭看了下 在這裡記錄下。方便自己也方便了他人麼,不足地方請各位指出呢!

其實壓縮檔案並不是太難,在這裡主要就是對IO流、ZIP的運用,挺有意思的一個案例。

現在對過程捋一下哈

首先,壓縮檔案要清楚需要用到的各種流,其次 要對資料夾和檔案進行分類處理,在這裡想對來說資料夾是相對來說較難的一個(因為用到回撥函式,這點對於新手來說可能不是太容易想到,感覺好神奇),兩者之間共性就是都要先建立一個以檔案目錄為名的zip壓縮檔案,然後將資料寫入到新建的zip中,完成檔案的壓縮。

個人認為真正的難點,在於理清楚FileOutputStream、ZipOutputStream和BufferedOutputStream三者之間的關係,這點尤其重要(這點 我在程式碼中有註釋解釋,希望認真看 搞清邏輯)。  好了,廢話不多說,直接上碼,畢竟程式碼才是實打實的麼

壓縮檔案程式碼:(包含丟擲的異常)

package com.tpad.compress;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.swing.JOptionPane;

class ZipCompress {

private String zipFileName;
private String sourceFileName;

public ZipCompress(String zipFileName, String sourceFileName) {
this.zipFileName = zipFileName;
this.sourceFileName = sourceFileName;
}

public void zip() throws MyZipException, IOException {

System.out.println("壓縮中...");

ZipOutputStream out = null;
BufferedOutputStream bos = null;
File sourceFile = null;
try {
out = new ZipOutputStream(new FileOutputStream(zipFileName)); // 建立一個zip輸出流
bos = new BufferedOutputStream(out); // 建立一個新的緩衝輸出流,以將資料寫入指定的位置
sourceFile = new File(sourceFileName);

compress(out, bos, sourceFile, sourceFile.getName());
} catch (MyZipException e) {
// TODO: handle exception
throw new MyZipException(e.getMessage());
} finally {
closeT(out);
closeT(bos);
}
System.out.println("壓縮完成");
}

private void closeT(Closeable c) {
// TODO Auto-generated method stubsss
// 為防止記憶體洩漏以及程式碼優化,寫了一個關閉流的方法
// 流 不為空時,關閉
if (c != null) {
try {
c.close();
} catch (IOException e) {
// TODO: handle exception
}
}
}

public void compress(ZipOutputStream out, BufferedOutputStream bos, File sourceFile, String base)
throws MyZipException {
BufferedInputStream bis = null;
try {
if (sourceFile.isDirectory()) {

File[] flist = sourceFile.listFiles(); // 獲取檔案目錄內檔案個數

if (flist.length == 0) {
System.out.println(base + "/");
// 空的檔案條目
// putNextEntry:開始編寫新的ZIP檔案條目,並將流定位到ZIP檔案開頭
// ZipEntry:建立具有指定名稱的新ZIP條目(建立一個以base為名的zip壓縮檔案)
out.putNextEntry(new ZipEntry(base + "/")); // 建立壓縮的子目錄
} else {
for (int i = 0; i < flist.length; i++) {
// 如果資料夾下還有檔案的話,使用回撥函式對下一層進行處理
compress(out, bos, flist[i], base + "/" + flist[i].getName());
}
}
} else {
// 不是檔案目錄(檔案)

out.putNextEntry(new ZipEntry(base)); // 建立以base為名的zip壓縮檔案
// 建立緩衝輸入流
bis = new BufferedInputStream(new FileInputStream(sourceFile));
int len = 0; // 記錄要寫入的位元組數
byte[] by = new byte[1024 * 5]; // 記錄讀取的資料
System.out.println(base);

while ((len = bis.read(by)) != -1) {
bos.write(by, 0, len); // 將資料寫入
}
closeT(bis);// 關閉流
}
} catch (IOException e) {
// TODO: handle exception
throw new MyZipException(e.getMessage());
}
}
}

public class CompressDemo {

public static void main(String[] args) throws MyZipException, IOException {
ZipCompress zipCom = null;
try {
zipCom = new ZipCompress("d:\\faaa.zip", "d:\\faaa\\");
zipCom.zip();
JOptionPane.showMessageDialog(null, "ok");
} catch (MyZipException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
}

下面是本人寫的異常:(僅供參考)

package com.tpad.compress;

@SuppressWarnings("serial")
public class MyZipException extends Exception {

public MyZipException(){
super();
}

public MyZipException(String str){
super(str);
}
}