1.首先,列举以下会提及到的三种解压方式:操作7z.exe解压、使用ant-1.9.6.jar解压、使用zip4j-1.3.2.jar解压。
2.第一种:java操作7z.exe解压文件,其实就是通过java内置的类来输入命令操作exe,相关的7z.exe命令详解
1) 打开上面的7z.exe下载链接,打开可以看到7za.exe, 7zxa.dll,copy到项目的tool文件夹下;
2) 测试类:
package unpack;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class 7ZipTool {
private String path;
private final static String defaultPath=".\\tool\\7z.exe";
private final static String[] exts={"rar","zip","7z","tar","tgz","gz","bzip2"};
private final static String wrongPasswordMsg="Wrong password?";
public 7ZipTool(){
this(defaultPath);
}
public 7ZipTool(String path){
this.path=path;
}
public boolean isSupport(File file) {
if(!file.isFile()){
return false;
}
String fileName=file.getAbsolutePath().toLowerCase();
for(int i=0; i<exts.length; i++){
if(fileName.endsWith("."+exts[i])){
return true;
}
}
return false;
}
public void unpack(File source, File target, boolean iter,
boolean isRemove) throws NeosUnpackWrongPasswordException{
if(!target.exists()){
target.mkdirs();
}
if(!target.isDirectory()){
return;
}
if(!iter){
if(isSupport(source)){
unpack(source, target.getAbsolutePath());
if(isRemove){
source.delete();
}
}
}else{
if(source.isDirectory()){
String destPath;
if(!source.equals(target)){
String sourceFileName=source.getName();
destPath=target.getAbsolutePath()+"\\"+sourceFileName;
}else{
destPath=target.getAbsolutePath();
}
File dest=new File(destPath);
File[] children=source.listFiles();
for(int i=0; i<children.length; i++){
unpack(children[i],dest,true,isRemove);
}
}else{
if(isSupport(source)){
unpack(source, target.getAbsolutePath());
if(isRemove){
source.delete();
}
unpack(target, target, true, isRemove);
}
}
}
}
private void unpack(File file, String dest) throws NeosUnpackWrongPasswordException{
String cmd=path+" x \""+file.getAbsolutePath()+"\" -o\""+dest+"\" -p12345 -y";
Runtime rt = Runtime.getRuntime();
try {
Process p = rt.exec(cmd);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
boolean isContainEncryptFile=false;
while((s=bufferedReader.readLine()) != null){
if(s.contains(wrongPasswordMsg)){
isContainEncryptFile=true;
continue;
}
}
p.waitFor();
p.destroy();
if(isContainEncryptFile){
throw new NeosUnpackWrongPasswordException(file);
}
} catch (IOException e) {
e.printStackTrace();
} catch(InterruptedException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws NeosUnpackWrongPasswordException {
7ZipTool tool = new 7ZipTool();
tool.unpack(new File("C:\\Users\\Desktop\\Desktop.Zip"),
new File("C:\\Users\\Desktop"), true, false);
}
}
3.第二种:使用ant-1.9.6.jar。
1) 测试类:
import java.io.File;
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;
public class ZipDecompressing {
/**
* @param sourcefiles
* 源文件(服务器上的zip包存放地址)
* @param decompreDirectory
* 解压缩后文件存放的目录
* @throws IOException
* IO异常
*/
public static void unzip(String sourcefiles, String decompreDirectory) throws IOException {
ZipFile readfile = null;
try {
readfile = new ZipFile(sourcefiles);
Enumeration<?> takeentrie = readfile.getEntries();
ZipEntry zipEntry = null;
File credirectory = new File(decompreDirectory);
credirectory.mkdirs();
while (takeentrie.hasMoreElements()) {
zipEntry = (ZipEntry) takeentrie.nextElement();
String entryName = zipEntry.getName();
InputStream in = null;
FileOutputStream out = null;
try {
if (zipEntry.isDirectory()) {
String name = zipEntry.getName();
name = name.substring(0, name.length() - 1);
File createDirectory = new File(decompreDirectory + File.separator + name);
createDirectory.mkdirs();
} else {
int index = entryName.lastIndexOf("\\");
if (index != -1) {
File createDirectory = new File(
decompreDirectory + File.separator + entryName.substring(0, index));
createDirectory.mkdirs();
}
index = entryName.lastIndexOf("/");
if (index != -1) {
File createDirectory = new File(
decompreDirectory + File.separator + entryName.substring(0, index));
createDirectory.mkdirs();
}
File unpackfile = new File(decompreDirectory + File.separator + zipEntry.getName());
in = readfile.getInputStream(zipEntry);
out = new FileOutputStream(unpackfile);
int c;
byte[] by = new byte[1024];
while ((c = in.read(by)) != -1) {
out.write(by, 0, c);
}
out.flush();
}
} catch (IOException ex) {
throw new IOException("解压失败:" + ex.toString());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException ex) {
}
}
in = null;
out = null;
}
}
} catch (IOException ex) {
throw new IOException("解压失败:" + ex.toString());
} finally {
if (readfile != null) {
try {
readfile.close();
} catch (IOException ex) {
throw new IOException("解压失败:" + ex.toString());
}
}
}
}
public static void main(String[] args) throws IOException {
ZipDecompressing.unzip("C:\\Users\\Downloads\\1324.zip",
"D:\\workplace\\tool");
}
}
4.第三种:使用zip4j-1.3.2.jar。
1) 测试类:
package test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
public class Zip4j_test {
private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
private static String CHARSET = "GBK"; // 文件名编码
private static boolean IS_LOOP = true; // 是否解压子目录的压缩包
private static boolean IS_REMOVE = false; // 是否删除源文件
private static String FILETYPE = "zip"; // 压缩包扩展名
/**
* 解压文件
* @param sourceFilePath 源文件路径
* @param destDirectory 解压路径
* @param password 压缩包密码
* @param FileNameCharset 文件编码
* @param isLoop 是否解压子目录的压缩包
* @param isRemove 是否删除源文件
*/
public static void unpack(String sourceFilePath, String destDirectory, String password,
String FileNameCharset, boolean isLoop, boolean isRemove) {
cachedThreadPool.execute(new Runnable() {
public void run() {
// System.out.println("--> 线程: " + Thread.currentThread().getName());
ZipFile zipFile;
try {
zipFile = new ZipFile(sourceFilePath);
if (zipFile.isEncrypted() && password != null) {
zipFile.setPassword(password);
}
zipFile.setFileNameCharset(FileNameCharset); // 设置文件名编码
if (!zipFile.isValidZipFile()) {
// 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
throw new ZipException("zip file is invalid.");
}
File destDir = new File(destDirectory); // 解压目录
if (destDir.isDirectory() && !destDir.exists()) {
destDir.mkdir();
}
System.out.println("--> 解压: " + sourceFilePath + " 到: " +destDirectory);
zipFile.extractAll(destDirectory);
List<File> filelist = getFileList(destDirectory, FILETYPE);
System.out.println("--> size: " + filelist.size());
// if( isLoop || (hasZip(filelist) && !isLoop) ) {
if( isLoop && hasZip(filelist) ) {
System.out.println("---> 遍历子压缩包 : "+ filelist.size());
for(File file: filelist) {
// System.out.println(file.getAbsolutePath());
// System.out.println(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")));
unpack(file.getAbsolutePath(),
file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")));
}
}
} catch (ZipException e) {
e.printStackTrace();
}
}
});
}
// 解压到destDirectory目标目录,压缩包附带密码
public static void unpack(String sourceFilePath, String destDirectory, String password) {
unpack(sourceFilePath, destDirectory, password, CHARSET, IS_LOOP, IS_REMOVE);
}
// 解压到destDirectory目标目录,压缩包附带密码
public static void unpack(String sourceFilePath, String destDirectory, String password, String FileNameCharset) {
unpack(sourceFilePath, destDirectory, password, FileNameCharset, IS_LOOP, IS_REMOVE);
}
// 解压到destDirectory目标目录,是否解压子目录的压缩包
public static void unpack(String sourceFilePath, String destDirectory, boolean isLoop) {
// if(!isLoop)
// unzip(sourceFilePath, destDirectory);
// else
unpack(sourceFilePath, destDirectory, null, CHARSET, isLoop, IS_REMOVE);
}
// 解压到destDirectory目标目录
public static void unpack(String sourceFilePath, String destDirectory) {
// unzip(sourceFilePath, destDirectory);
if(destDirectory != null)
unpack(sourceFilePath, destDirectory, null, CHARSET, IS_LOOP, IS_REMOVE);
else
unpack(sourceFilePath);
}
// 解压到当前目录
public static void unpack(String sourceFilePath) {
unpack(sourceFilePath, new File(sourceFilePath).getParentFile().getAbsolutePath());
}
//
public static void unzip(String sourcefiles, String decompreDirectory) {
org.apache.tools.zip.ZipFile readfile = null;
try {
readfile = new org.apache.tools.zip.ZipFile(sourcefiles);
Enumeration<?> takeentrie = readfile.getEntries();
org.apache.tools.zip.ZipEntry zipEntry = null;
File credirectory = new File(decompreDirectory);
credirectory.mkdirs();
while (takeentrie.hasMoreElements()) {
zipEntry = (org.apache.tools.zip.ZipEntry) takeentrie.nextElement();
String entryName = zipEntry.getName();
InputStream in = null;
FileOutputStream out = null;
try {
if (zipEntry.isDirectory()) {
String name = zipEntry.getName();
name = name.substring(0, name.length() - 1);
File createDirectory = new File(decompreDirectory + File.separator + name);
createDirectory.mkdirs();
} else {
int index = entryName.lastIndexOf("\\");
if (index != -1) {
File createDirectory = new File(
decompreDirectory + File.separator + entryName.substring(0, index));
createDirectory.mkdirs();
}
index = entryName.lastIndexOf("/");
if (index != -1) {
File createDirectory = new File(
decompreDirectory + File.separator + entryName.substring(0, index));
createDirectory.mkdirs();
}
File unpackfile = new File(decompreDirectory + File.separator + zipEntry.getName());
in = readfile.getInputStream(zipEntry);
out = new FileOutputStream(unpackfile);
int c;
byte[] by = new byte[1024];
while ((c = in.read(by)) != -1) {
out.write(by, 0, c);
}
out.flush();
}
} catch (IOException ex) {
throw new IOException("解压失败:" + ex.toString());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException ex) {
}
}
in = null;
out = null;
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (readfile != null) {
try {
readfile.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
/**
* 判断目录下是否有压缩包
* @param fileList
* @return
*/
public static boolean hasZip(List<File> fileList) {
for (File file: fileList) {
if(file.getName().toLowerCase().endsWith(FILETYPE.toLowerCase()))
return true;
}
return false;
}
/**
* 获取目录下后缀名为endwith的文件
* @param strPath 文件夹路径
* @param endwith 后缀名
* @return
*/
public static List<File> getFileList(String strPath, String endwith) {
List<File> filelist = new ArrayList<>();
File dir = new File(strPath);
File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
if (files != null) {
for (int i = 0; i < files.length; i++) {
String fileName = files[i].getName();
if (files[i].isDirectory()) { // 判断是文件还是文件夹
System.out.println("---> 文件夹:" + files[i].getName());
return getFileList(files[i].getAbsolutePath(), endwith); // 获取文件绝对路径
} else if (fileName.toLowerCase().endsWith(endwith.toLowerCase())) { // 判断文件名是否以.xml结尾
String strFileName = files[i].getAbsolutePath();
System.out.println("---> 文件:" + files[i].getName());
filelist.add(files[i]);
} else {
System.out.println("---> 不处理:"+files[i].getName());
continue;
}
}
}
else
System.out.println("文件夹为空");
return filelist;
}
public static void main(String[] args) {
try {
ZipFile zipFile = new ZipFile("D:\\workplace\\zip\\abc.zip");
if (zipFile.isEncrypted()) {
// if yes, then set the password for the zip file
zipFile.setPassword("1234");
}
zipFile.setFileNameCharset("GBK"); // 设置文件名编码,在GBK系统中需要设置
if (!zipFile.isValidZipFile()) { // 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等
throw new ZipException("压缩文件不合法,可能被损坏.");
}
File destDir = new File("D:\\workplace"); // 解压目录
if (destDir.isDirectory() && !destDir.exists()) {
destDir.mkdir();
}
zipFile.extractAll("D:\\workplace");
/*
List fileHeaderList = zipFile.getFileHeaders();
for (int i = 0; i < fileHeaderList.size(); i++) {
FileHeader fileHeader = (FileHeader)fileHeaderList.get(i);
zipFile.extractFile(fileHeader, "D:\\workplace");
}
*/
} catch (ZipException e) {
e.printStackTrace();
}
}
@Test
public void pubic() throws InterruptedException {
// TODO Auto-generated method stub
Zip4j_test.unpack("D:\\workplace\\zip\\abc.Zip",
"D:\\workplace\\test",
"1234");
Thread.sleep(60000);
}
}
部分参考:
1.https://snowolf.iteye.com/blog/643010
注:
1. 有时候gz文件不一定是valid的,所以可能会遇到:Java java.io.IOException: Not in GZIP format