Java Zip 压缩、解压
2016-06-02 00:00
429 查看
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import android.text.TextUtils;
/**
* zip压缩解压工具
*/
public class ZipUtils {
private static final int BUFF_SIZE = 1024;
/**
* @param zos
* 压缩流
* @param parentDirName
* 父目录
* @param file
* 待压缩文件
* @param buffer
* 缓冲区
* @return 只要目录中有一个文件压缩失败,就停止并返回
*/
private static boolean zipFile(ZipOutputStream zos, String parentDirName, File file, byte[] buffer) {
String zipFilePath = parentDirName + file.getName();
if (file.isDirectory()) {
zipFilePath += File.separator;
for (File f : file.listFiles()) {
if (!zipFile(zos, zipFilePath, f, buffer)) {
return false;
}
}
return true;
} else {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry zipEntry = new ZipEntry(zipFilePath);
zipEntry.setSize(file.length());
zos.putNextEntry(zipEntry);
int count;
while ((count = bis.read(buffer)) != -1) {
zos.write(buffer, 0, count);
}
bis.close();
return true;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
}
/**
* @param srcPath
* 待压缩的文件或目录
* @param dstPath
* 压缩后的zip文件
* @return 只要待压缩的文件有一个压缩失败就停止压缩并返回(等价于windows上直接进行压缩)
*/
public static boolean zipFile(String srcPath, String dstPath) {
File srcFile = new File(srcPath);
if (!srcFile.exists()) {
return false;
}
byte[] buffer = new byte[BUFF_SIZE];
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dstPath));
boolean result = zipFile(zos, "", srcFile, buffer);
zos.close();
return result;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
/**
* @param srcPath
* 待解压的zip文件
* @param dstPath
* zip解压后待存放的目录
* @return 只要解压过程中发生错误,就立即停止并返回(等价于windows上直接进行解压)
*/
public static boolean unzipFile(String srcPath, String dstPath) {
if(TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(dstPath)) {
return false;
}
File srcFile = new File(srcPath);
if(!srcFile.exists() || !srcFile.getName().toLowerCase(Locale.getDefault()).endsWith("zip")) {
return false;
}
File dstFile = new File(dstPath);
if(!dstFile.exists() || !dstFile.isDirectory()) {
dstFile.mkdirs();
}
try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(srcFile));
BufferedInputStream bis = new BufferedInputStream(zis);
ZipEntry zipEntry = null;
byte[] buffer = new byte[BUFF_SIZE];
if(!dstPath.endsWith(File.separator)) {
dstPath += File.separator;
}
while((zipEntry = zis.getNextEntry()) != null) {
String fileName = dstPath + zipEntry.getName();
File file = new File(fileName);
File parentDir = file.getParentFile();
if(!parentDir.exists()) {
parentDir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
while(bis.read(buffer) != -1) {
fos.write(buffer);
}
fos.close();
}
bis.close();
zis.close();
return true;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
}
感谢评论中的这位小哥指出这个问题
InputStream 的 read 方法会尽可能地填充满这个 buffer,同时返回当前填充的长度。
(1)当快到文件末尾的时候,可能只填充了部分 buffer,所以此时就需要按读取的实际长度来操作得到的这个 buffer 了
(2)当读到文件末尾的 EOF 标志的时候会返回 -1,可以通过这个特殊标志来结束循环。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import android.text.TextUtils;
/**
* zip压缩解压工具
*/
public class ZipUtils {
private static final int BUFF_SIZE = 1024;
/**
* @param zos
* 压缩流
* @param parentDirName
* 父目录
* @param file
* 待压缩文件
* @param buffer
* 缓冲区
* @return 只要目录中有一个文件压缩失败,就停止并返回
*/
private static boolean zipFile(ZipOutputStream zos, String parentDirName, File file, byte[] buffer) {
String zipFilePath = parentDirName + file.getName();
if (file.isDirectory()) {
zipFilePath += File.separator;
for (File f : file.listFiles()) {
if (!zipFile(zos, zipFilePath, f, buffer)) {
return false;
}
}
return true;
} else {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry zipEntry = new ZipEntry(zipFilePath);
zipEntry.setSize(file.length());
zos.putNextEntry(zipEntry);
int count;
while ((count = bis.read(buffer)) != -1) {
zos.write(buffer, 0, count);
}
bis.close();
return true;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
}
/**
* @param srcPath
* 待压缩的文件或目录
* @param dstPath
* 压缩后的zip文件
* @return 只要待压缩的文件有一个压缩失败就停止压缩并返回(等价于windows上直接进行压缩)
*/
public static boolean zipFile(String srcPath, String dstPath) {
File srcFile = new File(srcPath);
if (!srcFile.exists()) {
return false;
}
byte[] buffer = new byte[BUFF_SIZE];
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dstPath));
boolean result = zipFile(zos, "", srcFile, buffer);
zos.close();
return result;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
/**
* @param srcPath
* 待解压的zip文件
* @param dstPath
* zip解压后待存放的目录
* @return 只要解压过程中发生错误,就立即停止并返回(等价于windows上直接进行解压)
*/
public static boolean unzipFile(String srcPath, String dstPath) {
if(TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(dstPath)) {
return false;
}
File srcFile = new File(srcPath);
if(!srcFile.exists() || !srcFile.getName().toLowerCase(Locale.getDefault()).endsWith("zip")) {
return false;
}
File dstFile = new File(dstPath);
if(!dstFile.exists() || !dstFile.isDirectory()) {
dstFile.mkdirs();
}
try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(srcFile));
BufferedInputStream bis = new BufferedInputStream(zis);
ZipEntry zipEntry = null;
byte[] buffer = new byte[BUFF_SIZE];
if(!dstPath.endsWith(File.separator)) {
dstPath += File.separator;
}
while((zipEntry = zis.getNextEntry()) != null) {
String fileName = dstPath + zipEntry.getName();
File file = new File(fileName);
File parentDir = file.getParentFile();
if(!parentDir.exists()) {
parentDir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
while(bis.read(buffer) != -1) {
fos.write(buffer);
}
fos.close();
}
bis.close();
zis.close();
return true;
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
}
感谢评论中的这位小哥指出这个问题
InputStream 的 read 方法会尽可能地填充满这个 buffer,同时返回当前填充的长度。
(1)当快到文件末尾的时候,可能只填充了部分 buffer,所以此时就需要按读取的实际长度来操作得到的这个 buffer 了
(2)当读到文件末尾的 EOF 标志的时候会返回 -1,可以通过这个特殊标志来结束循环。
相关文章推荐
- SpringMVC学习笔记(7):处理模型数据(2)
- JAVA原子性操作
- 有关JAVA虚拟机规范的官方文档 收藏
- java线程初体验(三国战绩)
- Java控制台编译报错(编码GBK的不可映射字符)
- java(1)
- SpringJDBC与MyBatis
- Spring与MyBatis整合
- java分页原理和文件上传下载
- spring事务管理一:关于事务管理的接口
- Spring(Scheduler)
- java通过坐标截取整图代码
- eclipse 本地连接hadoop 进行开发
- 算法系列(五)排序算法下篇--如何超越排序算法下界
- 【java基础】String Pool
- 创建简单springMVC项目
- Java枚举的7种常见用法
- Java语言实现CRC32校验
- Java8 新特性----函数式接口,以及和Lambda表达式的关系
- 【JAVA】七 JAVA Dictionary 一 HashTable