All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mizhousoft.commons.io.zip.ZipUtils Maven / Gradle / Ivy

package com.mizhousoft.commons.io.zip;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import org.apache.commons.io.FileUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mizhousoft.commons.io.ZipException;

/**
 * unzip工具类
 *
 * @version
 */
public class ZipUtils
{
	private static final Logger LOG = LoggerFactory.getLogger(ZipUtils.class);

	/**
	 * 是否有效的ZIP文件
	 * 
	 * @param file
	 * @return
	 * @throws ZipException
	 */
	public static void checkZip(File file) throws ZipException
	{
		ZipFile zipFile = null;

		try
		{
			zipFile = new ZipFile(file);

			Enumeration entries = (Enumeration) zipFile.getEntries();
			while (entries.hasMoreElements())
			{
				ZipEntry zipEntry = entries.nextElement();
				String filename = zipEntry.getName();

				validateFilename(filename, ".");
			}
		}
		catch (IOException e)
		{
			throw new ZipException("Validate zip file failed.", e);
		}
		finally
		{
			closeZipFile(zipFile);
		}
	}

	/**
	 * 校验文件名是否合法
	 * 
	 * @param filename
	 * @param intendedDir
	 * @throws IOException
	 * @throws ZipException
	 */
	private static void validateFilename(String filename, String intendedDir) throws IOException, ZipException
	{
		File f = new File(filename);
		String canonicalPath = f.getCanonicalPath();

		File iD = new File(intendedDir);
		String canonicalID = iD.getCanonicalPath();

		if (!canonicalPath.startsWith(canonicalID))
		{
			throw new ZipException("File is outside extraction target directory, file name is " + filename + '.');
		}
	}

	/**
	 * 解压文件
	 * 
	 * @param file
	 * @param unzipPath
	 * @throws ZipException
	 */
	public static void unzip(File file, String unzipPath) throws ZipException
	{
		File unzipDir = new File(unzipPath);
		if (unzipDir.exists() && unzipDir.isDirectory())
		{
			deleteSubFiles(unzipDir);
		}
		else
		{
			boolean ok = unzipDir.mkdirs();
			if (!ok)
			{
				throw new ZipException("Create directory failed, directory is " + unzipPath + ".");
			}
		}

		ZipFile zipFile = null;

		try
		{
			zipFile = new ZipFile(file);
			doUnzip(zipFile, unzipPath);
		}
		catch (IOException e)
		{
			throw new ZipException(e.getMessage(), e);
		}
		catch (ZipException e)
		{
			try
			{
				deleteSubFiles(unzipDir);
			}
			catch (Throwable e1)
			{
				LOG.error(e1.getMessage(), e1);
			}

			throw e;
		}
		finally
		{
			closeZipFile(zipFile);
		}
	}

	/**
	 * 删除子文件
	 * 
	 * @param parentFile
	 * @throws ZipException
	 */
	private static void deleteSubFiles(File parentFile) throws ZipException
	{
		if (!parentFile.exists())
		{
			return;
		}

		File[] subFiles = parentFile.listFiles();
		if (null != subFiles)
		{
			for (File subFile : subFiles)
			{
				try
				{
					FileUtils.forceDelete(subFile);
				}
				catch (IOException e)
				{
					throw new ZipException(e.getMessage(), e);
				}
			}
		}
	}

	/**
	 * 解压文件
	 * 
	 * @param zipFile
	 * @param unzipPath
	 * @throws ZipException
	 */
	private static void doUnzip(ZipFile zip, String unzipPath) throws ZipException
	{
		Enumeration entries = (Enumeration) zip.getEntries();
		while (entries.hasMoreElements())
		{
			ZipEntry zipEntry = entries.nextElement();
			if (zipEntry.isDirectory())
			{
				String unzipFileDir = unzipPath + File.separator + zipEntry.getName();
				File unzipFileDirFile = new File(unzipFileDir);
				if (!unzipFileDirFile.exists())
				{
					boolean ok = unzipFileDirFile.mkdirs();
					if (!ok)
					{
						throw new ZipException("Create directory failed, directory is " + unzipFileDir + ".");
					}
				}
			}
			else
			{
				String path = unzipPath + File.separator + zipEntry.getName();

				try (InputStream is = zip.getInputStream(zipEntry);
				        FileOutputStream fos = new FileOutputStream(new File(path)))
				{

					byte[] buff = new byte[2048];
					int size = is.read(buff);
					while (size > 0)
					{
						fos.write(buff, 0, size);
						size = is.read(buff);
					}

					fos.flush();
				}
				catch (IOException e)
				{
					throw new ZipException(e.getMessage(), e);
				}
			}
		}
	}

	/**
	 * 关闭zip流
	 * 
	 * @param zipFile
	 */
	public static void closeZipFile(ZipFile zipFile)
	{
		if (null != zipFile)
		{
			try
			{
				zipFile.close();
			}
			catch (IOException e)
			{
				LOG.error(e.getMessage(), e);
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy