package fyhh.stream.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ZipUtil {
//存放已压缩的文件目录
private Map<String,ZipEntry> map = new HashMap<String,ZipEntry>();
public static void main(String[] args) throws IOException {
ZipUtil zu = new ZipUtil();
// zu.unwrap(new File("h"), new File("tt.zip"));
zu.wrap(new File("tt.zip"), new File("tt"));
}
/**
* 解压缩文件
* @param source 待解压文件
* @param destination 目标文件
* @return
* @throws IOException if an I/O error has occurred
* @throws ZipException if a ZIP format error has occurred
*/
public boolean wrap(File source,File destination) throws ZipException, IOException {
if(!source.exists()) {
throw new FileNotFoundException("源文件不存在");
}
if(destination.exists()) {
if(!destination.isDirectory()) {
destination.mkdirs();
}
}else {
destination.mkdirs();
}
ZipFile zipfile = new ZipFile(source);
Enumeration<?> entries = zipfile.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
File file = new File(destination.getPath()+File.separator+entry.getName());
System.out.println(entry.getName());
if(entry.isDirectory()) {
file.mkdirs();
continue;
}
InputStream is = zipfile.getInputStream(entry);
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destination.getPath()+File.separator+entry.getName()));
byte[] bytes = new byte[1024];
int len = 0;
while((len=bis.read(bytes))!=-1) {
bos.write(bytes,0,len);
}
bis.close();
bos.close();
}
zipfile.close();
return false;
}
/**
* 压缩文件
* @param source 待压缩文件夹
* @param destination 压缩文件
* @return
* @throws IOException
*/
public boolean unwrap(File source,File destination) throws IOException {
//1.创建压缩文件
if(!source.exists()) {
throw new ZipException("待压缩文件不存在");
}
destination.delete();
if(!destination.exists()) {
destination.createNewFile();
}
//2.压缩文件
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destination));
if(source.isDirectory()) {
addDirectory(source,zos,true);
}else {
addFile(source,zos);
}
zos.close();
return true;
}
/**
* 压缩文件添加目录
*
* @param file
* @param zos
* @throws IOException
*/
private void addDirectory(File file, ZipOutputStream zos, boolean bool) throws IOException {
String[] paths = file.getPath().split("\\/");
StringBuilder builder = new StringBuilder();
for(String path : paths) {
if(path.trim().isEmpty()) {
continue;
}
builder.append(path);
String tpath = builder.toString();
ZipEntry entry = new ZipEntry(tpath+"/");
if(map.get(entry.getName()) == null) {
map.put(entry.getName(), entry);
zos.putNextEntry(entry);
zos.closeEntry();
}
builder.append("/");
}
if(bool) {
File[] files = file.listFiles();
for(File f : files) {
if(f.isDirectory()) {
addDirectory(f, zos, true);
}else {
addFile(f, zos);
}
}
}
}
/**
* 压缩文件添加文件
*
* @param file
* @param zos
* @throws IOException
*/
private void addFile(File file, ZipOutputStream zos) throws IOException {
File parent = file.getParentFile();
if(parent!=null) {
if(map.get(new ZipEntry(parent.getPath()+"/").getName())!=null) {
ZipEntry entry = new ZipEntry(file.getPath());
if(map.get(entry.getName())==null) {
zos.putNextEntry(entry);
copyFile(file,zos);
zos.closeEntry();
map.put(entry.getName(), entry);
}
}else {
addDirectory(parent, zos, false);
}
}
}
/**
* 复制文件
*
* @param src
* @param dest
* @return
* @throws IOException
*/
public void copyFile(File src,ZipOutputStream zos) throws IOException {
//参数校验
if(!src.exists()) {
throw new FileNotFoundException("待复制文件未找到");
}
//完成复制
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(src));
byte[] bytes = new byte[1024];
int len = 0;
while((len=bis.read(bytes))!=-1) {
zos.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(bis != null) {
bis.close();
}
}
}
}
上面的代码有部分没考虑到,导致代码较复杂,修改后的代码如下:
package fyhh.stream.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ZipUtil {
public static void main(String[] args) throws IOException {
ZipUtil zu = new ZipUtil();
zu.unwrap(new File("h"), new File("tt.zip"));
// zu.wrap(new File("tt.zip"), new File("tt"));
}
/**
* 解压缩文件
* @param source 待解压文件
* @param destination 目标文件
* @return
* @throws IOException if an I/O error has occurred
* @throws ZipException if a ZIP format error has occurred
*/
public boolean wrap(File source,File destination) throws ZipException, IOException {
if(!source.exists()) {
throw new FileNotFoundException("源文件不存在");
}
if(destination.exists()) {
if(!destination.isDirectory()) {
destination.mkdirs();
}
}else {
destination.mkdirs();
}
ZipFile zipfile = new ZipFile(source);
Enumeration<?> entries = zipfile.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
File file = new File(destination.getPath()+File.separator+entry.getName());
System.out.println(entry.getName());
if(entry.isDirectory()) {
file.mkdirs();
continue;
}
InputStream is = zipfile.getInputStream(entry);
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destination.getPath()+File.separator+entry.getName()));
byte[] bytes = new byte[1024];
int len = 0;
while((len=bis.read(bytes))!=-1) {
bos.write(bytes,0,len);
}
bis.close();
bos.close();
}
zipfile.close();
return false;
}
/**
* 压缩文件
* @param source 待压缩文件夹
* @param destination 压缩文件
* @return
* @throws IOException
*/
public boolean unwrap(File source,File destination) throws IOException {
//1.创建压缩文件
if(!source.exists()) {
throw new ZipException("待压缩文件不存在");
}
destination.delete();
if(!destination.exists()) {
destination.createNewFile();
}
//2.压缩文件
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destination));
if(source.isDirectory()) {
addDirectory(source,zos);
}else {
addFile(source,zos);
}
zos.close();
return true;
}
/**
* 压缩文件添加目录
*
* @param file
* @param zos
* @throws IOException
*/
private void addDirectory(File file, ZipOutputStream zos) throws IOException {
ZipEntry entry = new ZipEntry(file.getPath()+"/");
zos.putNextEntry(entry);
zos.closeEntry();
File[] files = file.listFiles();
for(File f : files) {
if(f.isDirectory()) {
addDirectory(f, zos);
}else {
addFile(f, zos);
}
}
}
/**
* 压缩文件添加文件
*
* @param file
* @param zos
* @throws IOException
*/
private void addFile(File file, ZipOutputStream zos) throws IOException {
ZipEntry entry = new ZipEntry(file.getPath());
zos.putNextEntry(entry);
copyFile(file,zos);
zos.closeEntry();
}
/**
* 复制文件
*
* @param src
* @param dest
* @return
* @throws IOException
*/
public void copyFile(File src,ZipOutputStream zos) throws IOException {
//参数校验
if(!src.exists()) {
throw new FileNotFoundException("待复制文件未找到");
}
//完成复制
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(src));
byte[] bytes = new byte[1024];
int len = 0;
while((len=bis.read(bytes))!=-1) {
zos.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(bis != null) {
bis.close();
}
}
}
}
可以这样改的原因就是lFile#istFiles方法,逐层遍历。