Java解压Zip文件 小结

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

2.https://blog.csdn.net/educast/article/details/38755287

注:

1. 有时候gz文件不一定是valid的,所以可能会遇到:Java java.io.IOException: Not in GZIP format

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值