Android zip文件压缩与解压

Android zip文件压缩与解压

Android开发中偶尔需要用到zip文件的压缩与解压,正好公司项目需要用到,趁此机会特意总结了下,分享给大家,也是对我学习Android的记录。

zip压缩

Android中的zip压缩主要用到两个类:ZipEntry,ZipOutputStream,ZipEntry类用于保存一些被压缩文件的信息,如文件名、修改时间等等,部分源码如下:

class ZipEntry implements ZipConstants, Cloneable { 
    String name;        // entry name
    long time = -1;     // modification time (in DOS time)
    long crc = -1;      // crc-32 of entry data
    long size = -1;     // uncompressed size of entry data
    long csize = -1;    // compressed size of entry data
    int method = -1;    // compression method
    int flag = 0;       // general purpose flag
    byte[] extra;       // optional extra field data for entry
    String comment;     // optional comment string for entry
    // Android-changed: Add dataOffset for internal use.
    long dataOffset;

而ZipOutputStream是目标zip文件的输出流。zip压缩一共分为三步:

  1. 获取相应的ZipOutputStream;
  2. 判断是否是文件夹

​ (1)是:递归;

​ (2)否:根据文件路径、文件名等获取相应的ZipEntry,然后将该文件写入ZipOutputStream;

  1. 关闭相应的输出流;

    /** * 压缩文件 * @param srcFile 待压缩的源文件 * @param rootPath 源文件的根路径 * @param zos Zip输出流 * @param comment 备注 * @return 压缩成功返回true * @throws IOException */
    private static boolean zipFile(final File srcFile,String rootPath,final ZipOutputStream zos,final String comment) throws IOException { 
            rootPath = rootPath + (isSpace(rootPath) ? "" : File.separator) + srcFile.getName();
            if (srcFile.isDirectory()) { 
                File[] fileList = srcFile.listFiles();
                if (fileList == null || fileList.length <= 0) { 
                    ZipEntry entry = new ZipEntry(rootPath + '/');
                    entry.setComment(comment);
                    zos.putNextEntry(entry);
                    zos.closeEntry();
                } else { 
                    for (File file : fileList) { 
                        if (!zipFile(file, rootPath, zos, comment)) return false;
                    }
                }
            } else { 
                InputStream is = null;
                try { 
                    is = new BufferedInputStream(new FileInputStream(srcFile));
                    ZipEntry entry = new ZipEntry(rootPath);
                    entry.setComment(comment);
                    zos.putNextEntry(entry);
                    byte buffer[] = new byte[BUFFER_LEN];
                    int len;
                    while ((len = is.read(buffer, 0, BUFFER_LEN)) != -1) { 
                        zos.write(buffer, 0, len);
                    }
                    zos.closeEntry();
                } finally { 
                    CloseUtils.closeIO(is);
                }
            }
            return true;
        }
    

zip解压

/** * Unzip the file by keyword. * * @param zipFile The ZIP file. * @param destDir The destination directory. * @param keyword The keyboard. * @return the unzipped files * @throws IOException if unzip unsuccessfully */
    public static List<File> unzipFileByKeyword(final File zipFile,final File destDir,final String keyword) throws IOException { 
        if (zipFile == null || destDir == null) return null;
        List<File> files = new ArrayList<>();
        ZipFile zip = new ZipFile(zipFile);
        Enumeration<?> entries = zip.entries();
        try { 
            if (isSpace(keyword)) { 
                while (entries.hasMoreElements()) { 
                    ZipEntry entry = ((ZipEntry) entries.nextElement());
                    String entryName = entry.getName();
                    if (entryName.contains("../")) { 
                        Log.e("ZipUtils", "it's dangerous!");//防止被利用漏洞恶意修改文件
                        return files;
                    }
                    if (!unzipChildFile(destDir, files, zip, entry)) return files;
                }
            } else { 
                while (entries.hasMoreElements()) { 
                    ZipEntry entry = ((ZipEntry) entries.nextElement());
                    String entryName = entry.getName();
                    if (entryName.contains("../")) { 
                        Log.e("ZipUtils", "it's dangerous!");
                        return files;
                    }
                    if (entryName.contains(keyword)) { 
                        if (!unzipChildFile(destDir, files, zip, entry)) return files;
                    }
                }
            }
        } finally { 
            zip.close();
        }
        return files;
    }

private static boolean unzipChildFile(final File destDir,final List<File> files,final ZipFile zip,final ZipEntry entry)
        throws IOException { 
        File file = new File(destDir, entry.getName());
        files.add(file);
        if (entry.isDirectory()) { 
            return createOrExistsDir(file);//创建文件夹
        } else { 
            if (!createOrExistsFile(file)) return false;
            InputStream in = null;
            OutputStream out = null;
            try { 
                in = new BufferedInputStream(zip.getInputStream(entry));
                out = new BufferedOutputStream(new FileOutputStream(file));
                byte buffer[] = new byte[BUFFER_LEN];
                int len;
                while ((len = in.read(buffer)) != -1) { 
                    out.write(buffer, 0, len);
                }
            } finally { 
                if (in != null) { 
                    in.close();
                }
                if (out != null) { 
                    out.close();
                }
            }
        }
        return true;
    }

备注:代码实例来自开源框架AndroidUtilCode,https://github.com/Blankj/AndroidUtilCode 开源了各种开发过程中的常用工具,五星推荐。

    原文作者:__高山流水
    原文地址: https://blog.csdn.net/shuaizhigen/article/details/88671079
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞