最近做個東西,需要強大的Java版壓縮組建支持,可惜沒有開源的,最後實在沒辦法了。決定自己實現個,反正JDK中提供了最基礎的API.
標題說WinRAR工具,誇大了,還沒WinRAR那麼強大,僅僅是一個zip工具組建,沒有GUI界面,只有工具方法。
目標:
實現一個像WinRAR、WinZip一樣可以同時混合壓縮或者解壓縮文件和文件夾的工具。目前僅支持zip文件,因為SUN Java API僅支持zip和gzip兩種格式,gzip就像玩具槍,不中用,就不說了,下面是實現代碼。
實現:
寥寥不到百行代碼就搞定了,難點在於一個遞歸算法。
import Java.io.*;
import Java.util.Collection;
import Java.util.Enumeration;
import Java.util.zip.ZipEntry;
import Java.util.zip.ZipFile;
import Java.util.zip.ZipOutputStream;
//import org.apache.tools.zip.ZipEntry;
//import org.apache.tools.zip.ZipOutputStream;
/**
* Java版的Zip工具
*
* @author leizhimin 2008-11-27 11:16:05
*/
public class ZipUtils {
private static final int BUFF_SIZE = 1024 * 1024; //1M Byte
/**
* 批量壓縮文件(夾)
*
* @param resFileList 要壓縮的文件(夾)列表
* @param zipFile 生成的壓縮文件
* @throws IOException 當壓縮過程出錯時拋出
*/
public static void zipFiles(Collection
ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
for (File resFile : resFileList) {
zipFile(resFile, zipout, "");
}
zipout.close();
}
/**
* 批量壓縮文件(夾)
*
* @param resFileList 要壓縮的文件(夾)列表
* @param zipFile 生成的壓縮文件
* @param comment 壓縮文件的注釋
* @throws IOException 當壓縮過程出錯時拋出
*/
public static void zipFiles(Collection
ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile), BUFF_SIZE));
for (File resFile : resFileList) {
zipFile(resFile, zipout, "");
}
zipout.setComment(comment);
zipout.close();
}
/**
* 解壓縮一個文件
*
* @param zipFile 壓縮文件
* @param folderPath 解壓縮的目標目錄
* @throws IOException 當壓縮過程出錯時拋出
*/
public static void upZipFile(File zipFile, String folderPath) throws IOException {
ZipFile zf = new ZipFile(zipFile);
for (Enumeration entries = zf.entries(); entrIEs.hasMoreElements();) {
ZipEntry entry = ((ZipEntry) entrIEs.nextElement());
InputStream in = zf.getInputStream(entry);
OutputStream out = new FileOutputStream(folderPath + File.separator + entry.getName());
byte buffer[] = new byte[BUFF_SIZE];
int realLength;
while ((realLength = in.read(buffer)) > 0) {
out.write(buffer, 0, realLength);
}
in.close();
out.close();
}
}
private static void zipFile(File resFile, ZipOutputStream zipout, String rootpath) throws IOException {
rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator) + resFile.getName();
if (resFile.isDirectory()) {
File[] fileList = resFile.listFiles();
for (File file : fileList) {
zipFile(file, zipout, rootpath);
}
} else {
byte buffer[] = new byte[BUFF_SIZE];
BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile), BUFF_SIZE);
zipout.putNextEntry(new ZipEntry(rootpath));
int realLength;
while ((realLength = in.read(buffer)) != -1) {
zipout.write(buffer, 0, realLength);
}
in.close();
zipout.flush();
zipout.closeEntry();
}
}
}
測試代碼:
public class Test {
public static void main(String[] args) throws IOException {
Collection
resFileList.add(new File("C:\\new.gif"));
resFileList.add(new File("C:\\HelloWorld.Java"));
resFileList.add(new File("C:\\crebas.sql"));
resFileList.add(new File("E:\\log.log"));
resFileList.add(new File("C:\\ooo\\upx\\"));
File zipFile = new File("C:\\txxxt.zip");
ZipUtils.zipFiles(resFileList, zipFile);
}
}
運行結果:
壓縮成功!
Process finished with exit code 0
呵呵,經過查看,沒問題,就是注釋亂碼。
經過反復測試,發現中文支持有問題。
google了一下解決方案,用ant包中的兩個類
//import org.apache.tools.zip.ZipEntry;
//import org.apache.tools.zip.ZipOutputStream;
替換Java包的對應的兩個類
import Java.util.zip.ZipFile;
import Java.util.zip.ZipOutputStream;
即可完美支持中文。