欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java压缩解压缩文件

程序员文章站 2022-05-15 10:58:13
...

前言

Android应用时时刻刻都应该考虑到为用户节省流量,消耗流量就是在消耗用户的金钱,这样的应用注定没法得到用户的青睐。数据压缩是减少用户流量的有效方法,现在来使用一下Java内部提供的Zip压缩实现。

解压Zip包

Java内部提供了ZipInputStream输入流专门负责读取zip类型的文件,通过ZipInputStream.nextEntry来遍历压缩包内部所有的资源文件和文件夹,在通过读取解压缩的数据放到新创建的文件里,实现zip包的解压操作。

在Android6.0以后外部存储设备的读写都需要动态权限申请,之前的Android6.0动态权限申请已经讨论过这个问题,这里不再给出权限请求代码。

// 解压目标目录
File dir = new File(getExternalCacheDir(), "tomcat");
if (!dir.exists()) {
    dir.mkdir();
}

ZipInputStream zipInputStream = null;
try {
    // 打开assets文件夹下面的zip包
    zipInputStream = new ZipInputStream(getAssets().open("tomcat.zip"));

    // 遍历zip包里的ZipEntry对象
    ZipEntry zipEntry = null;
    while ((zipEntry = zipInputStream.getNextEntry()) != null) {
        // 如果是缓存文件,不做任何处理
        if (zipEntry.getName().startsWith(".")) {
            continue;
        }

        // 如果是文件夹对象
        if (zipEntry.isDirectory()) {
            // 创建文件夹对象
            File childDir = new File(dir, zipEntry.getName());
            if (!childDir.exists()) {
                childDir.mkdirs();
            }
        } else {
            // 从zip包中读取解压缩的数据,并且拷贝到新创建的解压文件里
            File child = new File(dir, zipEntry.getName());
            FileUtils.copy(zipInputStream, child);
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.close(zipInputStream);
}

生成Zip包

生成Zip包相对麻烦一点,需要递归的遍历压缩的文件夹,同时记录当前所在文件路径位置,确保每个文件对象都会生成一个ZipEntry对象,但文件夹不必生成ZipEntry对象。

// 需要压缩到的文件夹
File dir = new File(getExternalCacheDir(), "tomcat");
if (!dir.exists()) return;

ZipOutputStream zipOutputStream = null;
try {
    // 生成zip包文件
    File zipFile = new File(getExternalCacheDir(), "ziptomcat.zip");
    if (!zipFile.exists()) {
        zipFile.createNewFile();
    }
    zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));

    // 递归压缩文件夹
    zipDir(dir, zipOutputStream, "");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.close(zipOutputStream);
}

private void zipDir(File dir, ZipOutputStream zipOutputStream, String path) {
    if (dir.isDirectory()) {
        // 如果是文件夹,压缩文件夹,不必为它生成ZipEntry
        for (File file : dir.listFiles()) {
            zipDir(file, zipOutputStream, path + File.separator + dir.getName());
        }
    } else {
        FileInputStream fis = null;
        try {
           // 为当前文件添加ZipEntry 
           zipOutputStream.putNextEntry(new ZipEntry(path + File.separator + dir.getName()));

          // 拷贝文件内容到压缩输出流里
            fis = new FileInputStream(dir);
            byte[] bytes = new byte[1024];
            int count = -1;
            while ((count = fis.read(bytes)) != -1) {
                zipOutputStream.write(bytes, 0, count);
            }
            // 结束这个ZipEntry的写入
            zipOutputStream.closeEntry();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(fis);
        }
    }
}