Posted on 2009-05-30 23:36
啥都寫點 閱讀(495)
評論(0) 編輯 收藏 所屬分類:
J2SE
關鍵技術:
- java.util.zip實現了Zip格式相關的類庫,使用ZIP格式壓縮和解壓縮文件時,需要導入該包。
- 使用ZipOutputStream可以實現文件壓縮,所有寫入到ZipOutputStream輸出流中的數據,都會被Zip格式壓縮。
- 每個被壓縮的文件或者目錄在Zip文件中都對應一個ZipEntry對象,每一個ZipEntry都有一個name屬性,表示它相對于Zip文件根目錄的相對路徑,對與目錄,路徑以“/”結尾,對于文件,路徑以文件名結尾。
- ZipOutputStream的putNextEntry方法往Zip文件中添加一個ZipEntry,緊接著寫入到該ZipOutputStream流中數據都被保存在這個ZipEntry種,直到調用ZipOutputStream的closeEntry方法。
- ZipFile表示一個Zip文件,它的entries方法能獲得Zip文件中所有的ZipEntry集合。
- ZipEntry的isDirctory方法判斷該ZipEntry是否代表一個目錄。getInputStream方法獲得ZipEntry的輸入流。
package book.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* 用ZIP壓縮和解壓縮文件或目錄
*/
public class CompressUtil {
/**
* 壓縮文件或者目錄
* @param baseDirName 壓縮的根目錄
* @param fileName 根目錄下待壓縮的文件或文件夾名,
* 星號*表示壓縮根目錄下的全部文件。
* @param targetFileName 目標ZIP文件
*/
public static void zipFile(String baseDirName, String fileName,
String targetFileName){
//檢測根目錄是否存在
if (baseDirName == null){
System.out.println("壓縮失敗,根目錄不存在:" + baseDirName);
return;
}
File baseDir = new File(baseDirName);
if (!baseDir.exists() || (!baseDir.isDirectory())){
System.out.println("壓縮失敗,根目錄不存在:" + baseDirName);
return;
}
String baseDirPath = baseDir.getAbsolutePath();
//目標文件
File targetFile = new File(targetFileName);
try{
//創建一個zip輸出流來壓縮數據并寫入到zip文件
ZipOutputStream out =new ZipOutputStream(
new FileOutputStream(targetFile));
if (fileName.equals("*")){
//將baseDir目錄下的所有文件壓縮到ZIP
CompressUtil.dirToZip(baseDirPath, baseDir, out);
} else {
File file = new File(baseDir, fileName);
if (file.isFile()){
CompressUtil.fileToZip(baseDirPath, file, out);
} else {
CompressUtil.dirToZip(baseDirPath, file, out);
}
}
out.close();
System.out.println("壓縮文件成功,目標文件名:" + targetFileName);
} catch (IOException e){
System.out.println("壓縮失敗:" + e);
e.printStackTrace();
}
}
/**
* 解壓縮ZIP文件,將ZIP文件里的內容解壓到targetDIR目錄下
* @param zipName 待解壓縮的ZIP文件名
* @param targetBaseDirName 目標目錄
*/
public static void upzipFile(String zipFileName, String targetBaseDirName){
if (!targetBaseDirName.endsWith(File.separator)){
targetBaseDirName += File.separator;
}
try {
//根據ZIP文件創建ZipFile對象
ZipFile zipFile = new ZipFile(zipFileName);
ZipEntry entry = null;
String entryName = null;
String targetFileName = null;
byte[] buffer = new byte[4096];
int bytes_read;
//獲取ZIP文件里所有的entry
Enumeration entrys = zipFile.entries();
//遍歷所有entry
while (entrys.hasMoreElements()) {
entry = (ZipEntry)entrys.nextElement();
//獲得entry的名字
entryName = entry.getName();
targetFileName = targetBaseDirName + entryName;
if (entry.isDirectory()){
// 如果entry是一個目錄,則創建目錄
new File(targetFileName).mkdirs();
continue;
} else {
// 如果entry是一個文件,則創建父目錄
new File(targetFileName).getParentFile().mkdirs();
}
//否則創建文件
File targetFile = new File(targetFileName);
System.out.println("創建文件:" + targetFile.getAbsolutePath());
//打開文件輸出流
FileOutputStream os = new FileOutputStream(targetFile);
//從ZipFile對象中打開entry的輸入流
InputStream is = zipFile.getInputStream(entry);
while ((bytes_read = is.read(buffer)) != -1){
os.write(buffer, 0, bytes_read);
}
//關閉流
os.close( );
is.close( );
}
System.out.println("解壓縮文件成功!");
} catch (IOException err) {
System.err.println("解壓縮文件失敗: " + err);
}
}
/**
* 將目錄壓縮到ZIP輸出流。
*/
private static void dirToZip(String baseDirPath, File dir,
ZipOutputStream out){
if (dir.isDirectory()){
//列出dir目錄下所有文件
File[] files = dir.listFiles();
// 如果是空文件夾
if (files.length == 0){
ZipEntry entry = new ZipEntry(getEntryName(baseDirPath, dir));
// 存儲目錄信息
try {
out.putNextEntry(entry);
out.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
for (int i=0; i<files.length; i++){
if (files[i].isFile()){
//如果是文件,調用fileToZip方法
CompressUtil.fileToZip(baseDirPath, files[i], out);
} else {
//如果是目錄,遞歸調用
CompressUtil.dirToZip(baseDirPath, files[i], out);
}
}
}
}
/**
* 將文件壓縮到ZIP輸出流
*/
private static void fileToZip(String baseDirPath, File file,
ZipOutputStream out){
FileInputStream in = null;
ZipEntry entry = null;
// 創建復制緩沖區
byte[] buffer = new byte[4096];
int bytes_read;
if (file.isFile()){
try {
// 創建一個文件輸入流
in = new FileInputStream(file);
// 做一個ZipEntry
entry = new ZipEntry(getEntryName(baseDirPath, file));
// 存儲項信息到壓縮文件
out.putNextEntry(entry);
// 復制字節到壓縮文件
while((bytes_read = in.read(buffer)) != -1){
out.write(buffer, 0, bytes_read);
}
out.closeEntry();
in.close();
System.out.println("添加文件"
+ file.getAbsolutePath() + "被到ZIP文件中!");
} catch (IOException e){
e.printStackTrace();
}
}
}
/**
* 獲取待壓縮文件在ZIP文件中entry的名字。即相對于跟目錄的相對路徑名
* @param baseDirPath
* @param file
* @return
*/
private static String getEntryName(String baseDirPath, File file){
if (!baseDirPath.endsWith(File.separator)){
baseDirPath += File.separator;
}
String filePath = file.getAbsolutePath();
// 對于目錄,必須在entry名字后面加上"/",表示它將以目錄項存儲。
if (file.isDirectory()){
filePath += "/";
}
int index = filePath.indexOf(baseDirPath);
return filePath.substring(index + baseDirPath.length());
}
public static void main(String[] args) {
//壓縮C盤下的temp目錄,壓縮后的文件是C:/temp.zip
String baseDirName = "C:/";
String fileName = "temp/";
String zipFileName = "C:/temp.zip";
CompressUtil.zipFile(baseDirName, fileName, zipFileName);
//將剛創建的ZIP文件解壓縮到D盤的temp目錄下
System.out.println();
fileName = "D:/temp";
CompressUtil.upzipFile(zipFileName, fileName);
}
}
--
學海無涯