有的时候,需要做文件的压缩、解压缩。
java自身提供了已压缩,解压缩的原生类库。不过有开源代码的话,我一般是选择使用开源类库。
下面就贴一下,我使用ant-1.6.5的zip压缩、解压缩的代码吧。
ZipUtil.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.CRC32;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
/**
* <p>
* Title: 压缩、解压缩,辅助类
* </p>
*
* @author mahh
*/
public class ZipUtil {
// ==========================================================================
// 压缩文件方法1
// ==========================================================================
/**
* @Description: 压缩一个文件夹或者一个文件
* @param sourceFilePath
* 源文件夹或者源文件
* @param destZip
* 压缩后的zip文件
* @author mahh
* @since:2015-2-28 上午09:36:32
*/
public static void zip1(String sourceFilePath, String destZip) {
FileUtil.createParentFile(destZip); // 目标文件不存在就创建一个
Project project = new Project();
Zip zip = new Zip();
zip.setProject(project);
zip.setDestFile(new File(destZip));// 设置生成的目标zip文件File对象
FileSet fileSet = new FileSet();
fileSet.setProject(project);
File sourceFile1 = new File(sourceFilePath);
if (sourceFile1.isDirectory()) {
fileSet.setDir(sourceFile1);// 设置将要进行压缩的源文件File对象
// fileSet.setIncludes("**/*.java"); //包括哪些文件或文件夹,只压缩目录中的所有java文件
// fileSet.setExcludes("**/*.java"); //排除哪些文件或文件夹,压缩所有的文件,排除java文件
} else {
fileSet.setFile(sourceFile1);// 设置将要进行压缩的源文件File对象
}
// 增加一个Fileset。 Zip中可以增加多个Fileset
zip.addFileset(fileSet);
zip.execute();
}
/**
* @Description:解压缩
* @param sourceZipFilePath
* 源压缩文件zip
* @param destZipDir
* 解压缩到文件夹路径
* @return
* @author mahh
* @since:2015-2-28 下午04:57:28
*/
public static void unZip1(String sourceZipFilePath, String destZipDir) {
FileUtil.createDir(destZipDir);
Project proejct = new Project();
Expand expand = new Expand();
expand.setProject(proejct);
expand.setSrc(new File(sourceZipFilePath));
expand.setOverwrite(false);// 是否覆盖
// 如果不写,非常可能出现解压缩后文件的文件名(包含中文)出现乱码
expand.setEncoding(System.getProperty("sun.jnu.encoding"));
File file = new File(destZipDir);
expand.setDest(file);
expand.execute();
}
// ==========================================================================
// 压缩文件方法2
// ==========================================================================
/**
* @Description: 将一组文件压缩到一个压缩文件中
* @param list
* 一组被压缩的源文件,文件不能是目录
* @param destZipFilePath
* 生成zip文件绝对路径
* @param inZipBasePath
* 被压缩文件在zip内,相对路径(如a/b/c),默认在ZIP根目录下。
* @return
* @author mahh
* @since:2015-2-28 下午05:09:33
*/
public static File zip2(List<File> list, String destZipFilePath,
String inZipBasePath) {
if (inZipBasePath == null) {
inZipBasePath = "";
}
inZipBasePath = buildFilePath(inZipBasePath);
File zipFile = FileUtil.createNewFile(destZipFilePath);// 目标文件不存在就创建一个
ZipOutputStream out = null;
try {
out = new ZipOutputStream(new FileOutputStream(zipFile));
for (int i = 0; i < list.size(); i++) {
File file = list.get(i);
if (!file.exists()) {
continue;
}
if (file.isDirectory()) {
doZipFolder(inZipBasePath, out, file);
} else {
doZipFile(inZipBasePath, out, file);
}
}
return zipFile;
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
closeZipOutStream(out);
}
}
/**
* @Description: 只压缩一个文件夹自己(不包含文件夹内部内容)
*/
private static void doZipFolder(String inZipBasePath, ZipOutputStream out,
File file) throws IOException {
ZipEntry ze = new ZipEntry(inZipBasePath + FileUtil.FILE_SEPARATOR
+ file.getName() + FileUtil.FILE_SEPARATOR);
ze.setTime(new Date().getTime());
ze.setSize(0);
ze.setMethod(ZipEntry.STORED);
ze.setCrc(new CRC32().getValue());
ze.setUnixMode(ZipFileSet.DEFAULT_DIR_MODE);
out.putNextEntry(ze);
}
/**
* @Description: 压缩一个文件
*/
private static void doZipFile(String inZipBasePath, ZipOutputStream out,
File file) throws IOException {
FileInputStream in = new FileInputStream(file);
out.putNextEntry(new ZipEntry(inZipBasePath + FileUtil.FILE_SEPARATOR
+ file.getName()));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
if (in != null) {
in.close();
}
}
private static void closeZipOutStream(ZipOutputStream out) {
if (out == null) {
return;
}
try {
out.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 返回字符串去除结尾的\或/
* @param path
* @return
* @author mahh
* @since:2015-2-28 上午10:36:31
*/
private static String buildFilePath(final String path) {
if (path == null) {
return "";
}
String retStr = path;
while (FileUtil.isFolderPath(retStr)) {
if (retStr.length() < 1) {
break;
}
retStr = retStr.substring(0, retStr.length() - 1);
}
return retStr;
}
// ==========================================================================
// 解压缩文件方法2
// ==========================================================================
/**
* @Description:解压缩
* @param sourceZipFilePath
* 源压缩文件zip
* @param destZipDir
* 解压缩到文件夹路径
* @return
* @author mahh
* @since:2015-2-28 下午03:47:26
*/
@SuppressWarnings("unchecked")
public static List<File> unZip2(String sourceZipFilePath, String destZipDir) {
List<File> res = new ArrayList<File>();
ZipFile zipFile = null;
try {
zipFile = new ZipFile(sourceZipFilePath);
java.util.Enumeration<ZipEntry> ele = zipFile.getEntries();
while (ele.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) ele.nextElement();
File f = null;
if (FileUtil.isFolderPath(zipEntry.getName())) {
// 解压缩一个文件夹
f = doUnZipFolder(destZipDir, zipFile, zipEntry);
} else {
// 解压缩一个文件
f = doUnZipFile(destZipDir, zipFile, zipEntry);
}
res.add(f);
}
} catch (Exception e) {
throw new RuntimeException("{{不是可用的zip文件!}}");
} finally {
try {
if (zipFile != null) {
zipFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return res;
}
/**
* @Description: 解压缩一个文件夹自己(不包含文件夹内部内容)
*/
private static File doUnZipFolder(String destZipDir, ZipFile zipFile,
ZipEntry zipEntry) throws IOException {
File f = FileUtil.createNewFile(destZipDir + FileUtil.FILE_SEPARATOR
+ zipEntry.getName());
return f;
}
/**
* @Description: 解压缩一个文件
*/
private static File doUnZipFile(String destZipDir, ZipFile zipFile,
ZipEntry zipEntry) throws IOException {
File f = null;
InputStream in = null;
FileOutputStream out = null;
try {
f = FileUtil.createNewFile(destZipDir + FileUtil.FILE_SEPARATOR
+ zipEntry.getName());
in = zipFile.getInputStream(zipEntry);
out = new FileOutputStream(f);
byte[] by = new byte[100000];
int c;
while ((c = in.read(by)) != -1) {
out.write(by, 0, c);
}
out.flush();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (in != null) {
in.close(); // 解压完成后注意关闭输入流对象
}
if (out != null) {
out.close(); // 解压完成后注意关闭输出流对象
}
}
return f;
}
}
FileUtil.java
import java.io.File;
import java.io.IOException;
/**
* <p>
* Title: 创建文件、文件夹工具类
* </p>
*
* @author mahh
*
*/
public class FileUtil {
/**
* 操作系统路径分割符
*/
public static final String FILE_SEPARATOR = System
.getProperty("file.separator");
/**
* @Description: 创建文件(自动创建路径不存在的文件夹)。
* @param path
* 文件路径
* @return
* @author mahh
* @since:2015-2-28 下午02:23:29
*/
public static File createNewFile(String path) {
File file = new File(path);
// 如果是以目录分隔符结尾,那么这个路径是一个文件夹
if (isFolderPath(path)) {
if (!file.exists()) {
file.mkdirs();
}
return file;
}
if (file.exists()) {
return file;
}
String absolutePath = file.getAbsolutePath();
// 创建文件上层目录
createDir(absolutePath.substring(0,
absolutePath.lastIndexOf(FILE_SEPARATOR)));
try {
// 创建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException();
}
return file;
}
public static void createParentFile(String path) {
File file = new File(path);
String absolutePath = file.getAbsolutePath();
// 创建文件上层目录
createDir(absolutePath.substring(0,
absolutePath.lastIndexOf(FILE_SEPARATOR)));
}
/**
* @Description: 创建文件夹
* @param dir
* @author mahh
* @since:2015-2-28 下午02:23:40
*/
public static void createDir(String dir) {
File file = new File(dir);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* @Description: 判断一个字符串是不是文件夹路径
* @param path
* @return
* @author mahh
* @since:2015-2-28 上午11:58:35
*/
public static boolean isFolderPath(String path) {
if (path == null) {
return false;
}
if (path.endsWith(FILE_SEPARATOR)) {
return true;
}
if (path.endsWith("/")) {
return true;
}
return false;
}
}