xqlee 795 0 2018-03-24 09:44:25

  • 1.说明

    zip的文件压缩和解压在文件的存放用的还是比较多的。这里写了一个zip的工具类通过Apache的compress依赖实现。方便移植。
  • 2.依赖

            <!-- 压缩 -->
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>commons-compress</artifactId>
    			<version>1.14</version>
    		</dependency>

 

  • 3.工具类实现

    package net.xqlee.project.utils.compress;
    
    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.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import org.apache.commons.compress.archivers.zip.Zip64Mode;
    import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
    import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
    import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
    import org.apache.commons.compress.utils.IOUtils;
    import org.apache.commons.lang.StringUtils;
    
    import net.xqlee.project.utils.exception.UtilException;
    
    /**
     * zip压缩算法工具类
     * 
     * @author xq
     * @JDK 1.7
     */
    public class ZipCompressUtils {
    	private ZipCompressUtils() {
    		// 禁止构造
    	}
    
    	/** 缓冲大小 **/
    	public static final int BUFFER_SIZE = 1024;
    	/** 系统默认字符集 **/
    	public static final String SYSTEM_ENCODING = System.getProperty("file.encoding");
    
    	/**
    	 * 解压zip文件,默认操作系统字符集编码
    	 * 
    	 * @param zipFile
    	 * @param destDir
    	 * @return
    	 * @throws UtilException
    	 */
    	public static List<String> unZip(final File zipFile, final String targetPath) throws UtilException {
    		try {
    			return unZip(new FileInputStream(zipFile), targetPath, SYSTEM_ENCODING);
    		} catch (FileNotFoundException e) {
    			throw new UtilException(e);
    		}
    	}
    
    	/**
    	 * 指定zip字符集解压文件
    	 * 
    	 * @param zipFile
    	 * @param targetPath
    	 * @param encoding
    	 * @return
    	 * @throws UtilException
    	 */
    	public static List<String> unZip(final File zipFile, final String targetPath, String encoding)
    			throws UtilException {
    		try {
    			return unZip(new FileInputStream(zipFile), targetPath, encoding);
    		} catch (FileNotFoundException e) {
    			throw new UtilException(e);
    		}
    	}
    
    	/**
    	 * 解压zip文件流
    	 * 
    	 * @param zipFileInputStream
    	 * @param targetPath
    	 * @return
    	 * @throws UtilException
    	 */
    	public static List<String> unZip(final InputStream zipFileInputStream, final String targetPath)
    			throws UtilException {
    		return unZip(zipFileInputStream, targetPath, SYSTEM_ENCODING);
    	}
    
    	/**
    	 * 解压 zip 文件
    	 * 
    	 * @param zipFileInputStream
    	 *            zip 压缩文件流
    	 * @param destDir
    	 *            zip 压缩文件解压后保存的目录
    	 * @return 返回 zip 压缩文件里的文件名的 list
    	 * @throws UtilException
    	 *             工具类处理的异常
    	 */
    	public static List<String> unZip(final InputStream zipFileInputStream, final String destDir, final String encoding)
    			throws UtilException {
    		// 如果 destDir 为 null, 空字符串, 或者全是空格, 则解压到压缩文件所在目录
    		String targetDir = "";
    		if (StringUtils.isBlank(destDir)) {
    			throw new UtilException("Target Path Can't Be Empty!");
    		} else {
    			targetDir = destDir.endsWith(File.separator) ? destDir : destDir + File.separator;
    		}
    
    		// 字符集处理
    		String fileEncoding = encoding;
    		if (StringUtils.isBlank(encoding)) {
    			fileEncoding = SYSTEM_ENCODING;
    		}
    
    		List<String> fileNames = new ArrayList<>();
    		try (ZipArchiveInputStream is = new ZipArchiveInputStream(
    				new BufferedInputStream(zipFileInputStream, BUFFER_SIZE), fileEncoding);) {
    			ZipArchiveEntry entry = null;
    			while ((entry = is.getNextZipEntry()) != null) {
    				String fileName = entry.getName();
    				fileNames.add(fileName);
    
    				if (entry.isDirectory()) {
    					File directory = new File(targetDir, fileName);
    					directory.mkdirs();
    				} else {
    					try (OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(targetDir, fileName)),
    							BUFFER_SIZE);) {
    						IOUtils.copy(is, os);
    					}
    				}
    			}
    		} catch (Exception e) {
    			throw new UtilException(e);
    		}
    		return fileNames;
    	}
    
    	/**
    	 * zip打包
    	 * 
    	 * @param files
    	 * @param zipFilePath
    	 * @throws UtilException
    	 */
    	public static void zip(File[] files, String zipFilePath,String encoding) throws UtilException {
    		if (files == null || files.length == 0) {
    			throw new UtilException("Files Is Null Or Empty!");
    		}
    		try {
    			File zipFile = new File(zipFilePath);
    			try (ZipArchiveOutputStream zipos = new ZipArchiveOutputStream(zipFile)) {
    				//字符集
    				zipos.setEncoding(encoding);
    				// 启用64模式
    				zipos.setUseZip64(Zip64Mode.AsNeeded);
    				// 将每个文件用ZipArchiveEntry封装
    				// 再用ZipArchiveOutputStream写到压缩文件中
    				for (File file : files) {
    					if (file != null && file.exists() && file.isFile()) {
    						ZipArchiveEntry archiveEntry = new ZipArchiveEntry(file, file.getName());
    						zipos.putArchiveEntry(archiveEntry);
    						try (InputStream is = new BufferedInputStream(new FileInputStream(file));) {
    							byte[] buffer = new byte[BUFFER_SIZE * 4];
    							int len = -1;
    							while ((len = is.read(buffer)) != -1) {
    								// 把缓冲区的字节写入到ZipArchiveEntry
    								zipos.write(buffer, 0, len);
    							}
    							// Writes all necessary data for this entry.
    							zipos.closeArchiveEntry();
    						}
    					}
    				}
    				zipos.finish();
    			}
    		} catch (Exception e) {
    			throw new UtilException(e);
    		}
    	}
    
    	/**
    	 * 压缩某个目录
    	 * 
    	 * @param dir
    	 * @param zipFilePath
    	 * @throws UtilException
    	 */
    	public static void zip(String dir, String zipFilePath,String encoding) throws UtilException {
    		if (StringUtils.isBlank(dir) || StringUtils.isBlank(zipFilePath)) {
    			throw new UtilException("Dir To Package Or Zip File Can't Be Empty");
    		}
    
    		Map<String, File> filesInfo = filesName(dir, dir);
    
    		Set<String> keys = filesInfo.keySet();
    
    		//
    		try {
    			File zipFile = new File(zipFilePath);
    			try (ZipArchiveOutputStream zipos = new ZipArchiveOutputStream(zipFile)) {
    				if (!StringUtils.isBlank(encoding)) {
    					zipos.setEncoding(encoding);
    				}
    				// 启用64模式
    				zipos.setUseZip64(Zip64Mode.AsNeeded);
    				// 将每个文件用ZipArchiveEntry封装
    				// 再用ZipArchiveOutputStream写到压缩文件中
    				Iterator<String> iterator = keys.iterator();
    				while (iterator.hasNext()) {
    					String string = (String) iterator.next();
    
    					File file = filesInfo.get(string);
    
    					ZipArchiveEntry archiveEntry = new ZipArchiveEntry(file, string);
    					zipos.putArchiveEntry(archiveEntry);
    					try (InputStream is = new BufferedInputStream(new FileInputStream(file));) {
    						byte[] buffer = new byte[BUFFER_SIZE * 4];
    						int len = -1;
    						while ((len = is.read(buffer)) != -1) {
    							// 把缓冲区的字节写入到ZipArchiveEntry
    							zipos.write(buffer, 0, len);
    						}
    						// Writes all necessary data for this entry.
    						zipos.closeArchiveEntry();
    					}
    
    				}
    				zipos.finish();
    			}
    		} catch (Exception e) {
    			throw new UtilException(e);
    		}
    	}
    
    	public static Map<String, File> filesName(String dirPath, String rootPath) {
    		Map<String, File> fileInfo = new HashMap<>();
    		File dir = new File(dirPath);
    		if (dir.exists() && dir.isDirectory()) {
    			File[] files = dir.listFiles();
    			for (File file : files) {
    				if (file.isDirectory()) {
    					Map<String, File> fs = filesName(file.getPath(), rootPath);
    					fileInfo.putAll(fs);
    				} else {
    					fileInfo.put(file.getPath().replace(rootPath, ""), file);
    				}
    			}
    		}
    		return fileInfo;
    	}
    
    	public static void main(String[] args) throws UtilException {
    		// String zipPath = "C:\\Users\\xq\\Desktop\\李小强工作交接内容.zip";
    		// String destDir = "C:\\Users\\xq\\Desktop\\zip";
    		// unZip(new File(zipPath), destDir);
    
    		// 打包
    		// File dir = new File(destDir);
    		// zip(dir.listFiles(), destDir + "\\test.zip");
    
    		zip("C:\\Users\\xq\\Desktop\\zip", "C:\\Users\\xq\\Desktop\\test.zip",null);
    
    	}
    }
    
    工具类最后有调用方式。