java zip 写_java zip

使用 java 原生 api 实现简单压缩

关键类:ZipOutputStream,ZipEntry

ZipOutputStream 压缩流,用与将数据写入 zip 中

ZipEntry 描述了 zip 文件的内部结构,ZipEntry 中存放着文件路径与文件数据的映射

eg: /mm/hello.java --> hello.java文件 ; /mm/nn/world.js --> world.js文件

因此在解压的时候就可以通过读取 ZipEntry 创建相对应的路径,再将文件数据写入对应路径,即可完成解压

zipOutputStream.putNextEntry(zipEntry) ,zipInputStream.getNextEntry()

java 原生 zip api 不支持中文,所以压缩中又出现中文字符的文件名时会出现乱码的情况

解决方法: 下载 apache-ant-zip.jar 使用 apache提供的 ZipOutputStream , ZipEntry,zipOutputStream.setEncoding("");

示例代码😜:

/**

* java zip解压缩工具

* zip文件中可以存在空目录,可以设置是否包含顶层目录 eg: /mm: (1.txt,nn/) --> xx.zip: (1.txt,mm/) (没有顶层目录mm)

* @Description: TODO

* @CreateTime: 2016年11月5日 下午5:31:41

* @author: 蕪園樓主

* @version V1.0

*/

public final class ZipUtil {

private static byte[] buffer = new byte[1024 * 10]; //压缩缓冲

private ZipUtil() {

// empty

}

/**

* 压缩一个目录

* @Description: TODO

* @CreateTime: 2016年11月5日 下午5:29:15

* @author: 蕪園樓主

* @param filePath 源文件绝对路径

* @param zipFilePath zip文件绝对路径 (如果此处是目录名,则默认使用源文件名作为zip文件名)

* @param keepTopDir zip文件中是否包含顶层目录

* @return

*/

public static File zipDir(String filePath, String zipFilePath, boolean keepTopDir) {

File target = null;

File source = new File(filePath);

if(!source.exists() || !source.isDirectory()){

return null;

}

target = new File(zipFilePath);

if(target.isDirectory()){ //如果是目录,则压缩文件名为源文件名

target = new File(target.getAbsolutePath(), source.getName().concat(".zip"));

}else if (target.isFile()) {

target.delete(); // 删除旧的文件

}else{ //不存在

if(! target.getName().matches(".+\\..+$")){ //一个不存在的目录,以是否有扩展名为判断是否是一个目录

target.mkdirs();

target = new File(target.getAbsolutePath(), source.getName().concat(".zip"));

}else{ //一个不存在的文件

if(! target.getParentFile().exists()){

target.getParentFile().mkdirs();

}

}

}

FileOutputStream fos = null;

ZipOutputStream zos = null;

try {

fos = new FileOutputStream(target);

zos = new ZipOutputStream(new BufferedOutputStream(fos));

// 添加对应的文件Entry

addEntry("", source, zos, keepTopDir);

} catch (IOException e) {

throw new RuntimeException(e);

} finally {

//关闭流

}

return target;

}

/**

* 压缩一个文件

* @Description: TODO

* @CreateTime: 2016年11月5日 下午5:27:10

* @author: 蕪園樓主

* @param filePath 源文件绝对路径

* @param zipDir zip文件父目录

* @param zipName zip文件名 (如果此处是目录名,则默认使用源文件名作为zip文件名)

* @return

*/

public static File zipFile(String filePath, String zipFilePath) throws Exception{

File target = null;

File source = new File(filePath);

if(!source.exists() || !source.isFile()){

throw new Exception("压缩源目录无效");

}

target = new File(zipFilePath);

if(target.isDirectory()){ //如果是目录,则压缩文件名为源文件名

target = new File(target.getAbsolutePath(), source.getName().concat(".zip"));

}else if (target.isFile()) {

target.delete(); // 删除旧的文件

}else{ //不存在

if(! target.getName().matches("\\..+$")){ //一个不存在的目录,以是否有扩展名为判断是否是一个目录

target.mkdirs();

target = new File(target.getAbsolutePath(), source.getName().concat(".zip"));

}else{

target.getParentFile().mkdirs();

}

}

FileOutputStream fos = null;

ZipOutputStream zos = null;

try {

fos = new FileOutputStream(target);

zos = new ZipOutputStream(new BufferedOutputStream(fos));

zos.setEncoding("utf-8"); //设置编码

// 添加对应的文件Entry

addEntry("", source, zos, true);

} catch (IOException e) {

throw new Exception("压缩文件内部结构构建失败");

} finally {

closeQuietly(zos, fos);

}

return target;

}

/**

*

* @Description: 压缩文件,构建压缩内部文件结构

* @CreateTime: 2016年11月5日 下午5:23:48

* @author: 蕪園樓主

* @param base

* @param source 被压缩源文件

* @param zos 压缩输出流

* @param dir 压缩文件中是否包含顶层目录

* @throws IOException

*/

private static void addEntry(String base, File source, ZipOutputStream zos, boolean dir)

throws IOException {

String entry = (dir) ? (base.concat(source.getName())) : base;

if (source.isDirectory()) {

File[] files = source.listFiles();

if(files == null || files.length < 1){ //空目录

zos.putNextEntry(new ZipEntry(entry));

zos.closeEntry();

return;

}

for (File file : files) {

// 递归列出目录下的所有文件,添加文件Entry

addEntry(((dir)?(entry.concat("/")):entry), file, zos, true);

}

} else {

FileInputStream fis = null;

BufferedInputStream bis = null;

try {

fis = new FileInputStream(source);

bis = new BufferedInputStream(fis, buffer.length);

int read = 0;

zos.putNextEntry(new ZipEntry(entry));

while ((read = bis.read(buffer, 0, buffer.length)) != -1) {

zos.write(buffer, 0, read);

}

zos.closeEntry();

}

finally {

//关闭流

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值