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);
}
}
}