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 -强引用&弱引用
⑴强引用(StrongReference) 就是通过new得的对象引用 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMe ...
- C/C++ qsort()快速排序用法
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));头文件stdlib.h ...
- Activity 和 Intent
Activity 和 Intent 一.Intent指向Activity 二.利用 Intent 向第二个 Activity 传数据 三.利用 Intent 接受第二个 Activity 的返回值 四 ...
- 使用boost中的property_tree实现配置文件
property_tree是专为配置文件而写,支持xml,ini和json格式文件 ini比较简单,适合简单的配置,通常可能需要保存数组,这时xml是个不错的选择. 使用property_tr ...
- __autoload()方法
php中__autoload()方法详解 PHP在魔术函数__autoload()方法出现以前,如果你要在一个程序文件中实例化100个对象,那么你必须用include或者require包含进来100个 ...
- 参考storm中的RotatingMap实现key超时处理
storm0.8.1以后的RotatingMap完全可以独立于storm用来实现hashmap的key超时删除,并调用回调函数 RotatingMap.java: import java.util.H ...
- 解决java mail发送TXT附件被直接显示在正文中的问题
这两天遇到一个问题,关于使用java mail发送邮件的问题. 详细是这样子的:我使用java mail发送异常报告邮件,邮件中有一个包含异常日志的附件,和关于设备信息的邮件正文.假设日志为log后缀 ...
- Hadoop MapReduce编程的一些个人理解
首先要实现mapreduce就要重写两个函数,一个是map 还有一个是reduce map(key ,value) map函数有两个參数,一个是key,一个是value 假设你的输入类型是TextIn ...
- 怎样基于谷歌地图的Server缓存公布Image Service服务
怎样基于谷歌地图的Server缓存公布Image Service服务 第一步:下载地图数据 下载安装水经注万能地图下载器,启动时仅仅选择电子.谷歌(这里能够依据自己的须要选择).例如以下图所看到的. ...
- 树后台数据存储(採用webmethod)
树后台数据存储 关于后台数据存储将集中在此篇解说 /* *作者:方浩然 *日期:2015-05-26 *版本号:1.0 */ using System; using System.Collection ...