summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-04-23 00:16:13 +0800
committerkeuin <[email protected]>2020-04-23 00:20:29 +0800
commit28ebd3ae91dc6087a9f9acd93f80dd92be2d64aa (patch)
tree9a051d4784cd41953a5c6aa02e55005e14d907bf /src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
parentd00b439204b7ddfe381f1ff7c0dc1f02e16da8de (diff)
Finish backup.
TODO: - restore
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java b/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
new file mode 100644
index 0000000..d92ab12
--- /dev/null
+++ b/src/main/java/com/keuin/kbackupfabric/util/ZipUtil.java
@@ -0,0 +1,221 @@
+package com.keuin.kbackupfabric.util;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.zip.*;
+
+public class ZipUtil {
+
+ /**
+ * 递归压缩文件夹
+ *
+ * @param srcRootDir 压缩文件夹根目录的子路径
+ * @param file 当前递归压缩的文件或目录对象
+ * @param zos 压缩文件存储对象
+ * @throws Exception
+ */
+ private static void zip(String srcRootDir, File file, ZipOutputStream zos) throws IOException {
+ if (file == null) {
+ return;
+ }
+
+ // 如果是文件,则直接压缩该文件
+ if (file.isFile()) {
+ int count, bufferLen = 1024;
+ byte[] data = new byte[bufferLen];
+
+ // 获取文件相对于压缩文件夹根目录的子路径
+ String subPath = file.getAbsolutePath();
+ int index = subPath.indexOf(srcRootDir);
+ if (index != -1) {
+ subPath = subPath.substring(srcRootDir.length() + File.separator.length());
+ }
+ ZipEntry entry = new ZipEntry(subPath);
+ zos.putNextEntry(entry);
+ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+ while ((count = bis.read(data, 0, bufferLen)) != -1) {
+ zos.write(data, 0, count);
+ }
+ bis.close();
+ zos.closeEntry();
+ }
+ // 如果是目录,则压缩整个目录
+ else {
+ // 压缩目录中的文件或子目录
+ File[] childFileList = file.listFiles();
+ for (int n = 0; n < childFileList.length; n++) {
+ childFileList[n].getAbsolutePath().indexOf(file.getAbsolutePath());
+ zip(srcRootDir, childFileList[n], zos);
+ }
+ }
+ }
+
+ /**
+ * 对文件或文件目录进行压缩
+ *
+ * @param srcPath 要压缩的源文件路径。如果是目录,则将递归压缩这个目录及其所有子文件、子目录树。
+ * @param zipPath 压缩文件保存的路径。注意:zipPath不能是srcPath路径下的子文件夹
+ * @param zipFileName 压缩文件名
+ * @throws Exception
+ */
+ public static void zip(String srcPath, String zipPath, String zipFileName) throws IOException, ZipUtilException {
+ if (srcPath.isEmpty() || zipPath.isEmpty() || zipFileName.isEmpty()) {
+ throw new ZipUtilException("Parameter for zip() contains null.");
+ }
+ CheckedOutputStream cos = null;
+ ZipOutputStream zos = null;
+ try {
+ File srcFile = new File(srcPath);
+
+ //判断压缩文件保存的路径是否为源文件路径的子文件夹,如果是,则抛出异常(防止无限递归压缩的发生)
+ if (srcFile.isDirectory() && zipPath.indexOf(srcPath) != -1) {
+ throw new ZipUtilException("Detected loop recursion in directory structure, please check symlink linking to parent directories.");
+ }
+
+ //判断压缩文件保存的路径是否存在,如果不存在,则创建目录
+ File zipDir = new File(zipPath);
+ if (!zipDir.exists() || !zipDir.isDirectory()) {
+ zipDir.mkdirs();
+ }
+
+ //创建压缩文件保存的文件对象
+ String zipFilePath = zipPath + File.separator + zipFileName;
+ File zipFile = new File(zipFilePath);
+ if (zipFile.exists()) {
+ //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+ SecurityManager securityManager = new SecurityManager();
+ securityManager.checkDelete(zipFilePath);
+ //删除已存在的目标文件
+ zipFile.delete();
+ }
+
+ cos = new CheckedOutputStream(new FileOutputStream(zipFile), new CRC32());
+ zos = new ZipOutputStream(cos);
+
+ //如果只是压缩一个文件,则需要截取该文件的父目录
+ String srcRootDir = srcPath;
+ if (srcFile.isFile() || true) { // Hack this stupid setting. We want to keep our least parent folder!
+ int index = srcPath.lastIndexOf(File.separator);
+ if (index != -1) {
+ srcRootDir = srcPath.substring(0, index);
+ }
+ }
+ //调用递归压缩方法进行目录或文件压缩
+ zip(srcRootDir, srcFile, zos);
+ zos.flush();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ try {
+ if (zos != null) {
+ zos.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 解压缩zip包
+ *
+ * @param zipFilePath zip文件的全路径
+ * @param unzipFilePath 解压后的文件保存的路径
+ * @param includeZipFileName 解压后的文件保存的路径是否包含压缩文件的文件名。true-包含;false-不包含
+ */
+ @SuppressWarnings("unchecked")
+ public static void unzip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws ZipUtilException, IOException {
+ if (zipFilePath.isEmpty() || unzipFilePath.isEmpty()) {
+ throw new ZipUtilException("Parameter for unzip() contains null.");
+ }
+ File zipFile = new File(zipFilePath);
+ // 如果解压后的文件保存路径包含压缩文件的文件名,则追加该文件名到解压路径
+ if (includeZipFileName) {
+ String fileName = zipFile.getName();
+ if (!fileName.isEmpty()) {
+ fileName = fileName.substring(0, fileName.lastIndexOf("."));
+ }
+ unzipFilePath = unzipFilePath + File.separator + fileName;
+ }
+ // 创建解压缩文件保存的路径
+ File unzipFileDir = new File(unzipFilePath);
+ if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
+ unzipFileDir.mkdirs();
+ }
+
+ // 开始解压
+ ZipEntry entry = null;
+ String entryFilePath = null, entryDirPath = null;
+ File entryFile = null, entryDir = null;
+ int index = 0, count = 0, bufferSize = 1024;
+ byte[] buffer = new byte[bufferSize];
+ BufferedInputStream bis = null;
+ BufferedOutputStream bos = null;
+ ZipFile zip = new ZipFile(zipFile);
+ Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
+ // 循环对压缩包里的每一个文件进行解压
+ while (entries.hasMoreElements()) {
+ entry = entries.nextElement();
+ // 构建压缩包中一个文件解压后保存的文件全路径
+ entryFilePath = unzipFilePath + File.separator + entry.getName();
+ // 构建解压后保存的文件夹路径
+ index = entryFilePath.lastIndexOf(File.separator);
+ if (index != -1) {
+ entryDirPath = entryFilePath.substring(0, index);
+ } else {
+ entryDirPath = "";
+ }
+ entryDir = new File(entryDirPath);
+ // 如果文件夹路径不存在,则创建文件夹
+ if (!entryDir.exists() || !entryDir.isDirectory()) {
+ entryDir.mkdirs();
+ }
+
+ // 创建解压文件
+ entryFile = new File(entryFilePath);
+ if (entryFile.exists()) {
+ // 检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+ SecurityManager securityManager = new SecurityManager();
+ securityManager.checkDelete(entryFilePath);
+ // 删除已存在的目标文件
+ entryFile.delete();
+ }
+
+ // 写入文件
+ bos = new BufferedOutputStream(new FileOutputStream(entryFile));
+ bis = new BufferedInputStream(zip.getInputStream(entry));
+ while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
+ bos.write(buffer, 0, count);
+ }
+ bos.flush();
+ bos.close();
+ }
+ zip.close();
+ }
+
+// public static void main(String[] args)
+// {
+// String zipPath = "d:\\ziptest\\zipPath";
+// String dir = "d:\\ziptest\\rawfiles";
+// String zipFileName = "test.zip";
+// try
+// {
+// zip(dir, zipPath, zipFileName);
+// }
+// catch (Exception e)
+// {
+// e.printStackTrace();
+// }
+//
+// String zipFilePath = "D:\\ziptest\\zipPath\\test.zip";
+// String unzipFilePath = "D:\\ziptest\\zipPath";
+// try
+// {
+// unzip(zipFilePath, unzipFilePath, true);
+// }
+// catch (Exception e)
+// {
+// e.printStackTrace();
+// }
+// }
+} \ No newline at end of file