设为首页 收藏本站
查看: 1300|回复: 0

[经验分享] org.apache.tools.zip实现文件的压缩和解压,支持中文

[复制链接]

尚未签到

发表于 2017-1-14 07:57:08 | 显示全部楼层 |阅读模式
刚开始用java.util.Zip,发现不支持中文(网上有修改的方法,但比较麻烦)
后改用org.apache.tools.zip
org.apache.tools.zip的使用网上有更简单的例子
下面的程序根据实际需求,实现了压缩指定目录下指定文件的方法


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import common.Logger;//in jxl.jar (excel)
public class ZipUtil {
/**
* zip操作帮助类
* bylijinnan
*/
final static Logger logger = Logger.getLogger(ZipUtil.class);
/**
* 打包指定目录下所有文件,包括子文件夹
* @param sourceFolder要打包的文件目录
* @param outputFolder生成的压缩文件存放的目录
* @param zipFileName生成的压缩文件名
* @throws IOException
*/
public static void zipFolder(String sourceFolder, String outputFolder,String zipFileName, String encoding) throws IOException {
if (isEmptyStr(sourceFolder) || isEmptyStr(outputFolder) || isEmptyStr(zipFileName)) {
logger.error("invalid parameters.");
return;
}
sourceFolder = formatFilePath(sourceFolder);
outputFolder = formatFilePath(outputFolder);
List<String> filelist = generateFileList(sourceFolder);
zipFileList(filelist, sourceFolder, outputFolder, zipFileName, encoding);
}

/**
* 打包指定的文件。要打包的文件在文件列表中指定
* @param filelist要打包的文件列表,这些文件是绝对路径
* @param outputFullFileName生成的压缩文件全名,目录+文件名
* @throws IOException
*/
public static void zipFileList(List<String> filelist, String sourceFolder, String outputFolder, String zipFileName, String encoding) throws IOException {
if (filelist == null || filelist.isEmpty()) {
logger.error("no files to be zip. filelist is null or empty.");
return;
}
if (isEmptyStr(outputFolder) || isEmptyStr(zipFileName)) {
logger.error("outputFolder and zipFileName are unspecified.");
return;
}
sourceFolder = formatFilePath(sourceFolder);
outputFolder = formatFilePath(outputFolder);
if (isEmptyStr(encoding)) {
encoding = "UTF-8";
}
File outputDir = new File(outputFolder);
if (!outputDir.exists()) {
outputDir.mkdirs();
}
byte[] buffer = new byte[1024];
String outputFullFileName = (outputFolder + "/" + zipFileName);
FileOutputStream fos = new FileOutputStream(outputFullFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
zos.setEncoding(encoding);
logger.info("Output to Zip : " + outputFullFileName);
for (String file : filelist) {
if (isEmptyStr(file)) {
continue;
}
logger.info("File Added : " + file);
ZipEntry ze = new ZipEntry(file);//这里用的是相对路径
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(sourceFolder + "/" + file);//这里是绝对路径
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
}
zos.closeEntry();
// remember close it
zos.close();
logger.info("Compress Done");
}
/**
* Traverse a directory and get all files(include the files in sub directory), add the file into fileList and return it.
*
* @param sourceFolder
*            file or directory
* @return filelist
*/
public static List<String> generateFileList(String sourceFolder) {
List<String> filelist = null;
if (!isEmptyStr(sourceFolder)) {
sourceFolder = formatFilePath(sourceFolder);
filelist = new ArrayList<String>();
File node = new File(sourceFolder);
generateFileListHelper(sourceFolder, node, filelist);
}
return filelist;
}
private static void generateFileListHelper(String sourceFolder, File node, List<String> filelist) {
// add file only
if (node.isFile()) {
String absoluteFile = node.getAbsoluteFile().toString();
String filepath = generateZipEntry(sourceFolder, absoluteFile);
filelist.add(filepath);
}
if (node.isDirectory()) {
String[] subNote = node.list();
for (String filename : subNote) {
File subFile = new File(node, filename);
generateFileListHelper(sourceFolder, subFile, filelist);
}
}
}
/**
* Format the file path for zip.
* Delete the "SOURCE_FOLDER" directory info,e.g.
* d:\ziptest\tmpty.txt --> tmpty.txt
* d:\ziptest\sub\t.xls -->sub\t.xls
*
* @param file
*            file path
* @return Formatted file path.
*/
private static String generateZipEntry(String sourceFolder, String file) {
logger.debug("sourceFolder=" + sourceFolder);
logger.debug("file=" + file);
String formattedPath = file.substring(sourceFolder.length() + 1);
formattedPath = formatFilePath(formattedPath);
logger.debug("formattedPath=" + formattedPath);
return formattedPath;
}
/**
* 将文件路径中的分隔符转换成"/",并去掉最后的分隔符(如果有)
* @param str文件路径
* @return 格式化后的文件路径
*/
public static String formatFilePath(String str) {
if (str != null && str.length() !=0) {
str = str .replaceAll("\\\\", "/");
}
if (str.endsWith("/")) {
str = str.substring(0, str.length()-1);
}
return str;
}
private static boolean isEmptyStr(String str) {
return str == null || str.length() == 0;
}
/**
* 解压zip文件,支持子文件夹和中文
* @param zipFileFullName .zip文件的完整名字,包括文件夹路径
* @param outputFolder解压到指定的文件夹。完整路径,如果不指定或者为null,则默认解压到压缩文件所在的当前文件夹
* @param encoding 编码格式
*/
@SuppressWarnings("rawtypes")
public static void unzip(String zipFileFullName, String outputFolder, String encoding) {
if (zipFileFullName == null || zipFileFullName.length() == 0) {
return;
}
if (!zipFileFullName.endsWith(".zip")) {
logger.error(zipFileFullName + " is not a zip file.");
return;
}
//change file separator to "/"
zipFileFullName = zipFileFullName.replaceAll("\\\\", "/");
//find outputFolder
String inputFolder = zipFileFullName.replaceAll("/[^/]+\\.zip", "");
if (outputFolder == null || outputFolder.length() == 0) {
outputFolder = inputFolder;
}
outputFolder = outputFolder.replaceAll("\\\\", "/");
File outputFolderFile = new File(outputFolder);
if (!outputFolderFile.exists()) {
outputFolderFile.mkdirs();
}
try {
ZipFile zip = new ZipFile(zipFileFullName, encoding);
Enumeration zipFileEntries = zip.getEntries();
while (zipFileEntries.hasMoreElements()) {
ZipEntry entry =  (ZipEntry) zipFileEntries.nextElement();
String entryName = entry.getName();
logger.debug("Extracting,entryName=" + entryName);
/*用本程序中ZipUtil.zipFolder或者ZipUtil.zipFileList生成的zip文件,如果有子文件夹,entry.getName()会直接得到文件而略过了子文件夹:
* 程序生成,解压时输出:
* Extracting,entryName=sub/subsub/test.txt
* 压缩软件7-Zip生成,解压时输出:
* Extracting,entryName=sub/subsub/
* Extracting,entryName=sub/subsub/test.txt
* 因此要区别对待
*/
int lastSlashPos = entryName.lastIndexOf("/");
if (lastSlashPos != -1 ){
String folderStr = outputFolder + "/" + entryName.substring(0, lastSlashPos);
File folder = new File(folderStr);
if (!folder.exists()) {
folder.mkdirs();
}
}
if (!entryName.endsWith("/")) {//this entry is not a directory.
File outFile = new File(outputFolder + "/" + entryName);
FileOutputStream fos = new FileOutputStream(outFile);
Writer bw = new BufferedWriter(new OutputStreamWriter(fos, encoding));
InputStream in = zip.getInputStream(entry);
Reader reader = new InputStreamReader(in, encoding);
BufferedReader br =  new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
}
bw.close();
}
}
} catch (Exception e) {
logger.error("errors occur when decompressing.");
e.printStackTrace();
}
}
public static void main(String[] argv) {
String sourceFolder = "d:/ziptest";
String outputFolder = "d:/ziptest";
String outputFileName = "ziptest.zip";
try {
zipFolder(sourceFolder, outputFolder, outputFileName, "GB2312");
} catch (IOException e) {
e.printStackTrace();
}
String zipFileFullName = "d:\\ziptest\\ziptest.zip";
unzip(zipFileFullName, "d:\\ziptest\\unzip", "GB2312");
}

}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-328080-1-1.html 上篇帖子: [JMX一步步来] 5、用Apache的commons-modeler来辅助开发JMX 下篇帖子: windows2003下 apache ecshop实现二级域名和URL重写功能
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表