java.util.zip - Recreating directory structure(转)
include my own version for your reference.
We use this one to zip up photos to download so it works with various unzip programs. It preserves the directory structure and timestamps.
public static void createZipFile(File srcDir, OutputStream out,
boolean verbose) throws IOException { List<String> fileList = listDirectory(srcDir);
ZipOutputStream zout = new ZipOutputStream(out); zout.setLevel(9);
zout.setComment("Zipper v1.2"); for (String fileName : fileList) {
File file = new File(srcDir.getParent(), fileName);
if (verbose)
System.out.println(" adding: " + fileName); // Zip always use / as separator
String zipName = fileName;
if (File.separatorChar != '/')
zipName = fileName.replace(File.separatorChar, '/');
ZipEntry ze;
if (file.isFile()) {
ze = new ZipEntry(zipName);
ze.setTime(file.lastModified());
zout.putNextEntry(ze);
FileInputStream fin = new FileInputStream(file);
byte[] buffer = new byte[4096];
for (int n; (n = fin.read(buffer)) > 0;)
zout.write(buffer, 0, n);
fin.close();
} else {
ze = new ZipEntry(zipName + '/');
ze.setTime(file.lastModified());
zout.putNextEntry(ze);
}
}
zout.close();
} public static List<String> listDirectory(File directory)
throws IOException { Stack<String> stack = new Stack<String>();
List<String> list = new ArrayList<String>(); // If it's a file, just return itself
if (directory.isFile()) {
if (directory.canRead())
list.add(directory.getName());
return list;
} // Traverse the directory in width-first manner, no-recursively
String root = directory.getParent();
stack.push(directory.getName());
while (!stack.empty()) {
String current = (String) stack.pop();
File curDir = new File(root, current);
String[] fileList = curDir.list();
if (fileList != null) {
for (String entry : fileList) {
File f = new File(curDir, entry);
if (f.isFile()) {
if (f.canRead()) {
list.add(current + File.separator + entry);
} else {
System.err.println("File " + f.getPath()
+ " is unreadable");
throw new IOException("Can't read file: "
+ f.getPath());
}
} else if (f.isDirectory()) {
list.add(current + File.separator + entry);
stack.push(current + File.separator + f.getName());
} else {
throw new IOException("Unknown entry: " + f.getPath());
}
}
}
}
return list;
}
}
SEPARATOR constant is initialised with the System.getProperty("file.separator") which will give me the OS default file separator.
I would never hardcode a separator since that assumes that your code will only be deployed on a given OS
Don't use File.separator in ZIP. The separator must be "/" according to the spec. If you are on Windows, you must open file as "D:\dir\subdir\file" but ZIP entry must be "dir/subdir/file"
Just go through the source of java.util.zip.ZipEntry. It treats a ZipEntry as directory if its name ends with "/" characters. Just suffix the directory name with "/". Also you need to remove the drive prefix to make it relative.
Here is another example (recursive) which also lets you include/exclude the containing folder form the zip:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; public class ZipUtil { private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; public static void main(String[] args) throws Exception {
zipFile("C:/tmp/demo", "C:/tmp/demo.zip", true);
} public static void zipFile(String fileToZip, String zipFile, boolean excludeContainingFolder)
throws IOException {
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile)); File srcFile = new File(fileToZip);
if(excludeContainingFolder && srcFile.isDirectory()) {
for(String fileName : srcFile.list()) {
addToZip("", fileToZip + "/" + fileName, zipOut);
}
} else {
addToZip("", fileToZip, zipOut);
} zipOut.flush();
zipOut.close(); System.out.println("Successfully created " + zipFile);
} private static void addToZip(String path, String srcFile, ZipOutputStream zipOut)
throws IOException {
File file = new File(srcFile);
String filePath = "".equals(path) ? file.getName() : path + "/" + file.getName();
if (file.isDirectory()) {
for (String fileName : file.list()) {
addToZip(filePath, srcFile + "/" + fileName, zipOut);
}
} else {
zipOut.putNextEntry(new ZipEntry(filePath));
FileInputStream in = new FileInputStream(srcFile); byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int len;
while ((len = in.read(buffer)) != -1) {
zipOut.write(buffer, 0, len);
} in.close();
}
}
}
http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure
java.util.zip - Recreating directory structure(转)的更多相关文章
- Java.util.zip adding a new file overwrites entire jar?(转)
ZIP and TAR fomats (and the old AR format) allow file append without a full rewrite. However: The Ja ...
- java.util.zip.ZipException: invalid entry size 解决办法
启动maven项目时报java.util.zip.ZipException: invalid entry size (expected 7612 but got 5955 bytes) 可能是mave ...
- [Java 基础] 使用java.util.zip包压缩和解压缩文件
reference : http://www.open-open.com/lib/view/open1381641653833.html Java API中的import java.util.zip ...
- 启动TOMCAT报错 java.util.zip.ZipException: invalid LOC header (bad signature)
报错信息大致如下所示: at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect. ...
- java.util.zip.ZipOutputStream压缩无乱码(原创)
package io; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileI ...
- [java bug记录] java.util.zip.ZipException: invalid code lengths set
1. 描述:将代码迁移到maven工程,其中用ZipInputStream读取/src/main/resources下的zip文件时报错:“java.util.zip.ZipException: in ...
- java.util.zip压缩打包文件总结二: ZIP解压技术
一.简述 解压技术和压缩技术正好相反,解压技术要用到的类:由ZipInputStream通过read方法对数据解压,同时需要通过CheckedInputStream设置冗余校验码,如: Checked ...
- java.util.zip压缩打包文件总结一:压缩文件及文件下面的文件夹
一.简述 zip用于压缩和解压文件.使用到的类有:ZipEntry ZipOutputStream 二.具体实现代码 package com.joyplus.test; import java.io ...
- java.util.zip.GZIPInputStream.readUByte,Not in GZIP format错误处理
问题一: 使用webclient抓取网页时报错:(GZIPInputStream.java:207) atjava.util.zip.GZIPInputStream.readUShort(GZIPIn ...
随机推荐
- JAVA实现AES的加密和解密算法
原文 JAVA实现AES的加密和解密算法 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import ja ...
- Ruby on Rails: 使用devise+cancan+rolify建立完整的权限管理系
devise.cancan和rolify这三个组件结合,可以建立完整而强大的用户权限模型. devise介绍,负责用户注册.登录.退出.找回密码等操作.细节参考devise on github can ...
- 基于visual Studio2013解决C语言竞赛题之0708字符串查找
题目
- 基于visual Studio2013解决C语言竞赛题之1010计算
题目 解决代码及点评 /************************************************************************/ ...
- 融云(找到“每个App都有沟通的需求”的细分市场)
近日,国内著名App驾考宝典和融云达成合作,为应用增加IM功能,实现亿级用户之间聊天.消息一出,IM(即时通讯)领域的大佬,同时也是个上线不到两岁的新生力量,再次引发了行业的关注. 对业内人士而言,即 ...
- PHP学习之-1.4 计算表达式
计算表达式 不同于HTML和CSS,在PHP中做计算,比如我们写 echo 12*3 计算结果是36.代码如下 <?php echo 12*3;?> 实例 <!DOCTYPE HTM ...
- Java+7入门经典 - 6 扩展类与继承 Part 1/2
第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...
- Javascript 进阶 封装
js中处处是对象,面向对象的第一步当然就是封装了,由于Js中没有类的概念,所以封装起来也比较麻烦,下面介绍两种js的封装. 1.使用约定优先的原则,将所有的私有变量以_开头 <script ty ...
- 【图像识别】 图像处理和图像分析(leptonica)leptonica-1.68安装配置 (vs2008)
Leptonica Leptonica is a pedagogically-oriented open source site containing software that is broadly ...
- POJ 2175 spfa费用流消圈
题意:给出n栋房子位置和每栋房子里面的人数,m个避难所位置和每个避难所可容纳人数.然后给出一个方案,判断该方案是否最优,如果不是求出一个更优的方案. 思路:很容易想到用最小费用流求出最优时间,在与原方 ...