java对 zip文件的压缩和解压(ant解决中文乱码)
说明:
1、对于压缩的文件,当文件名称是中文时,若使用JDK API中自带的类(java.util.zip.ZipEntry; java.util.zip.ZipOutputStream;)进行压缩,压缩完成后,可以看到压缩包中的文件名称是乱码(文件的内容无乱码),所以使用ANT中的ant.jar中的类(org.apache.tools.zip.ZipEntry; org.apache.tools.zip.ZipOutputStream;)用来解决此问题;
2、解压缩时,如果压缩包中为空,则创建空文件夹
import 如下:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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 org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
一、压缩文件(ZIP):
/**
*@name 获取File对象
*@description 相关说明
*@param path 文件路径
*@return File
*@throws IOException
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static File getFile(String path) throws IOException {
// 创建文件对象
File file = null;
if (path != null && !path.equals("")) {
file = new File(path);
}
if (!file.exists()) {
file.createNewFile();
}
// 返回文件
return file;
}
/**
*@name 压缩文件
*@description 相关说明
*@param srcFilePath 源文件
*@param destZipFile 目标文件
*@return file 压缩文件的FILE对象
*@throws IOException
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static File getZipFile(String srcFilePath, String destZipFile) throws IOException {
return getZipFile(new File(srcFilePath),destZipFile);
}
/**
*@name 获取压缩文件的File
*@description 相关说明
*@param srcFile 源文件
*@param destZipFile 目标文件
*@return file 压缩文件的FILE对象
*@throws IOException
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static File getZipFile(File srcFile, String destZipFile) throws IOException {
final File zipFile = getFile(destZipFile);
// 文件输出流
final FileOutputStream outputStream =new FileOutputStream(zipFile);
// 压缩流
final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
if (srcFile.isDirectory()) {
directory(zipOutputStream, srcFile);
} else {
zipFile(srcFile, zipOutputStream);
}
// 关闭压缩流、文件流
zipOutputStream.close();
outputStream.close();
return zipFile;
}
/**
*@name 递归压缩目录结构
*@description 相关说明
*@param zipOutputStream 压缩文件流
*@param file file
*@throws IOException
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static void directory(ZipOutputStream zipOutputStream, File file) throws IOException {
final File[] files = file.listFiles();
for (File fileTemp : files) {
if (fileTemp.isDirectory()) {
directory(zipOutputStream, fileTemp);
} else {
zipFile(fileTemp, zipOutputStream);
}
} if (files.length == 0) {
try {
zipOutputStream.putNextEntry(new ZipEntry(getPath(file) + File.separator));
} catch (Exception e) {
e.printStackTrace();
} }
}
/**
*@name 获得该文件在压缩包中的相对路径
*@description 相关说明
*@param file File
*@return String
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static String getPath(File file) {
final String str1 = file.getAbsolutePath();
final int n1 = str1.length();
final String str2 = file.getAbsolutePath();
final int n2 = str2.length();
final String str3 = file.getName();
final int n3 = str3.length();
final String str = str2.substring(n1 - n3, n2);
return str;
}
/**
* 将文件数据写入文件压缩流
* @param file 带压缩文件
* @param zipOutputStream 压缩文件流
* @throws IOException
*/
private static void zipFile(File file, ZipOutputStream zipOutputStream) throws IOException {
if (file.exists()) {
if (file.isFile()) {
final FileInputStream fis = new FileInputStream(file);
final BufferedInputStream bis = new BufferedInputStream(fis);
final ZipEntry entry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(entry); final int MAX_BYTE = 10 * 1024 * 1024; // 最大流为10MB
long streamTotal = 0; // 接收流的容量
int streamNum = 0; // 需要分开的流数目
int leaveByte = 0; // 文件剩下的字符数
byte[] buffer; // byte数据接受文件的数据 streamTotal = bis.available(); // 获取流的最大字符数
streamNum = (int) Math.floor(streamTotal / MAX_BYTE);
leaveByte = (int) (streamTotal % MAX_BYTE); if (streamNum > 0) {
for (int i = 0; i < streamNum; i++) {
buffer = new byte[MAX_BYTE];
bis.read(buffer, 0, MAX_BYTE);
zipOutputStream.write(buffer, 0, MAX_BYTE);
}
} // 写入剩下的流数据
buffer = new byte[leaveByte];
bis.read(buffer, 0, leaveByte); // 读入流
zipOutputStream.write(buffer, 0, leaveByte); // 写入流
zipOutputStream.closeEntry(); // 关闭当前的zip entry // 关闭输入流
bis.close();
fis.close();
}
}
}
二、解压缩文件(ZIP)
/**
*@name 解压zip格式压缩包
*@description 相关说明
*@param sourceZip 源文件
*@param destDir 目标文件地址
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
@SuppressWarnings("unchecked")
private static void unzip(String sourceZip, String destDir) throws Exception {
ZipFile zipFile = null;
try {
final File f = new File(sourceZip);
if ((!f.exists()) && (f.length() <= 0)) {
throw new RuntimeException("要解压的文件不存在!");
}
//一定要加上编码,之前解压另外一个文件,没有加上编码导致不能解压
zipFile = new ZipFile(f, "gbk");
String gbkPath;
String strtemp;
final Enumeration<ZipEntry> e = zipFile.getEntries();
if (!e.hasMoreElements()) {
final File dir = new File(destDir + File.separator + f.getName().substring(0, f.getName().lastIndexOf(".")));
if (!dir.exists()) {
dir.mkdirs();
}
return;
}
while (e.hasMoreElements()) {
final org.apache.tools.zip.ZipEntry zipEnt = e.nextElement();
gbkPath = zipEnt.getName();
strtemp = destDir + File.separator + gbkPath;
if (zipEnt.isDirectory()) { //目录
final File dir = new File(strtemp);
if (!dir.exists()) {
dir.mkdirs();
}
continue;
} else if (zipEnt.getName().substring(zipEnt.getName().length() - 1, zipEnt.getName().length()).equals(File.separator)) {
final File dir = new File(strtemp);
if (!dir.exists()) {
dir.mkdirs();
}
continue;
} else {
// 读写文件
final InputStream is = zipFile.getInputStream(zipEnt);
final BufferedInputStream bis = new BufferedInputStream(is);
// 建目录
final String strsubdir = gbkPath;
for (int i = 0; i < strsubdir.length(); i++) {
if (strsubdir.substring(i, i + 1).equalsIgnoreCase("/")) {
final String temp = destDir + File.separator + strsubdir.substring(0, i);
final File subdir = new File(temp);
if (!subdir.exists()) {
subdir.mkdir();
}
}
}
final FileOutputStream fos = new FileOutputStream(strtemp);
final BufferedOutputStream bos = new BufferedOutputStream(fos);
int len;
final byte[] buff = new byte[1024];
while ((len = bis.read(buff)) != -1) {
bos.write(buff, 0, len);
}
bos.close();
fos.close();
}
}
} catch (Exception e) {
//logger.error("解压文件出现异常:", e);
throw e;
}finally{
zipFile.close();
}
} /**
*@name 解压文件用于后期扩展RAR等其他压缩格式
*@description 相关说明
*@param sourceFile 源文件
*@param destDir 目标路径
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
private static void unfile(String sourceFile, String destDir) throws Exception {
// 根据类型,进行相应的解压缩
final String type = sourceFile.substring(sourceFile.lastIndexOf(".") + 1);
final File dir = new File(destDir);
if(!dir.exists()){
dir.mkdirs();
}
if (type.toLowerCase().equals("zip")) {
unzip(sourceFile, destDir);
} else {
throw new RuntimeException("只支持zip格式的压缩包!"+type);
}
} /**
*@name 解压到指定目录
*@description 相关说明
*@param sourceFile 源文件
*@param destDir 目标目录
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static void deCompress(String sourceFile, String destDir) throws Exception {
if (sourceFile == null || destDir == null) {
throw new RuntimeException("目录不能为空");
}
// 保证文件夹路径最后是"/"或者"\"
final char lastChar = destDir.charAt(destDir.length() - 1);
if (lastChar != '/' && lastChar != '\\') {
unfile(sourceFile, destDir+File.separator);
}else{
unfile(sourceFile, destDir);
} } /**
*@name 解压到指定目录
*@description 相关说明
*@param sourceFile 源文件
*@param destDir 目标路径
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static void deCompress(File sourceFile, String destDir) throws Exception {
if (!sourceFile.exists() || sourceFile.isDirectory()) {
throw new RuntimeException("文件不存在");
}
deCompress(sourceFile.getPath(), destDir);
} /**
*@name 解压到当前目录
*@description 相关说明
*@param sourceFile 源文件
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static void deCompress(String sourceFile) throws Exception { // 获得文件目录
int i = sourceFile.lastIndexOf("/");
final int d = sourceFile.lastIndexOf("\\");
if (i == -1 && d == -1) {
throw new RuntimeException("目录separator异常");
} else if (i == -1) {
i = d;
}
final String destDir = sourceFile.substring(0, i + 1);
unfile(sourceFile, destDir);
} /**
*@name 解压到当前目录
*@description 相关说明
*@param sourceFile 源文件
*@throws Exception
*@author LJCH
*@history 修订历史(历次修订内容、修订人、修订时间等)
*/
public static void deCompress(File sourceFile) throws Exception {
if (!sourceFile.exists() || sourceFile.isDirectory()) {
throw new RuntimeException("文件不存在");
}
deCompress(sourceFile.getPath());
}
文中如有存在描述不正确,欢迎指正、补充!!!
java对 zip文件的压缩和解压(ant解决中文乱码)的更多相关文章
- ZIP文件流压缩和解压
前面写了一篇文章 "ZIP文件压缩和解压", 介绍了" SharpZipLib.Zip " 的使用, 最近的项目中,在使用的过程中, 遇到一些问题. 比如, 现 ...
- java实现文件的压缩和解压
java实现文件的压缩和解压 代码压缩实现 package com.hjh.demo.zip; import java.io.BufferedInputStream; import java.io.F ...
- C#文件或文件夹压缩和解压方法(通过ICSharpCode.SharpZipLib.dll)
我在网上收集一下文件的压缩和解压的方法,是通过ICSharpCode.SharpZipLib.dll 来实现的 一.介绍的目录 第一步:下载压缩和解压的 ICSharpCode.SharpZipLib ...
- linux下文件加密压缩和解压的方法
一.用tar命令 对文件加密压缩和解压 压缩:tar -zcf - filename |openssl des3 -salt -k password | dd of=filename.des3 此命 ...
- [Swift通天遁地]七、数据与安全-(9)文件的压缩和解压
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- C#文件或文件夹压缩和解压
C#文件或文件夹压缩和解压方法有很多,本文通过使用ICSharpCode.SharpZipLib.dll来进行压缩解压 1.新建一个winform项目,选择项目右键 管理NuGet程序包,搜索ICSh ...
- 用jdk1.6的pack200和unpack200,对jar文件进行压缩和解压 .pack.gz
用jdk1.6的pack200和unpack200,对jar文件进行压缩和解压 解压xxx.jar.pack.gz为xxx.jar:unpack200 -r xxx.jar.pack.gz xxx.j ...
- gz文件的压缩和解压
gz文件的压缩和解压 压缩: gzip filename 解压: gunzip filename.gz
- 【C#公共帮助类】WinRarHelper帮助类,实现文件或文件夹压缩和解压,实战干货
关于本文档的说明 本文档使用WinRAR方式来进行简单的压缩和解压动作,纯干货,实际项目这种压缩方式用的少一点,一般我会使用第三方的压缩dll来实现,就如同我上一个压缩类博客,压缩的是zip文件htt ...
随机推荐
- C和C++从零开始系列(一)
今天开始写下一系列C和C++从入门开始的文章. 简单说几句C和C++的关系.C语言早于C++. C语言 贝尔实验室的Ken Thompson发明了 UNIX,当时有个B语言的.后来D.M.Ritchi ...
- 源码分析 RocketMQ DLedger(多副本) 之日志复制(传播)
目录 1.DLedgerEntryPusher 1.1 核心类图 1.2 构造方法 1.3 startup 2.EntryDispatcher 详解 2.1 核心类图 2.2 Push 请求类型 2. ...
- Nginx的事件循环
首先事件循环的起点就是监听端口获取连接,我们可以在ngx_event_core_module模块的ngx_event_process_init函数中看到如下的代码: /* for each liste ...
- 【Web技术】399- 浅谈前端代码加密
作者简介:于航,PayPal Senior Software Engineer,在 PayPal 上海负责 Global GRT 平台相关的技术研发工作.曾任职于阿里巴巴.Tapatalk 等企业.f ...
- 【Web技术】334- yarn、npm、cnpm 三者如何优雅的在一起使用 ?
前端得包管理你有过几个? 一位用不好包管理器的前端,是一个入门级前端,一个用不好webpack的前端,是一个初级前端 三个包管理器是可以一起用的,只要你够胆大心细,就没任何问题! 在javeScrip ...
- 视频来了!Visual Studio Online 东半球首秀 @ .NET Conf 2019
2019 年 11 月 9 日,.NET Conf 2019 中国峰会于上海中谷小南国花园酒店举行,全国的 .NET 大咖相聚上海. 这次我演讲的主题是<Visual Studio Code — ...
- Java垃圾回收机制你还不明白?一线大厂面试必问的!
什么是自动垃圾回收? 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制. 所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未 ...
- mysql重点中的重点---->查询中的关键字优先级
1.from 找到表 2.where 拿着where指定的约束条件,去文件/表中取出一条条记录 3.group by 将取出的一条条记录进行分组group by ,如果没有group by ,则整体作 ...
- Caffe源码-SyncedMemory类
SyncedMemory类简介 最近在阅读caffe源码,代码来自BVLC/caffe,基本是参照网络上比较推荐的 Blob-->Layer-->Net-->Solver 的顺序来分 ...
- CUDA架构及对应编译参数
NVIDIA CUDA C++ 编译器 nvcc 基于每个内核,既可以用来产生特定于体系结构的 cubin 文件,又能产生前向兼容的 PTX 版本. 每个 cubin 文件针对特定的计算能力版本,并且 ...