Android Zip、tar+GZIP 压缩、解压

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import android.text.TextUtils;

/**
 * zip压缩解压工具
 */
public class ZipUtils {
    private static final int BUFF_SIZE = 1024;

    /**
     * @param zos
     *            压缩流
     * @param parentDirName
     *            父目录
     * @param file
     *            待压缩文件
     * @param buffer
     *            缓冲区
     * @return 只要目录中有一个文件压缩失败,就停止并返回
     */
    private static boolean zipFile(ZipOutputStream zos, String parentDirName, File file, byte[] buffer) {
        String zipFilePath = parentDirName + file.getName();
        if (file.isDirectory()) {
            zipFilePath += File.separator;
            for (File f : file.listFiles()) {
                if (!zipFile(zos, zipFilePath, f, buffer)) {
                    return false;
                }
            }
            return true;
        } else {
            try {
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                ZipEntry zipEntry = new ZipEntry(zipFilePath);
                zipEntry.setSize(file.length());
                zos.putNextEntry(zipEntry);
                int count;  
                while ((count = bis.read(buffer)) != -1) {  
                   zos.write(buffer, 0, count);  
                }
                bis.close();
                return true;
            } catch (FileNotFoundException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    }

    /**
     * @param srcPath
     *            待压缩的文件或目录
     * @param dstPath
     *            压缩后的zip文件
     * @return 只要待压缩的文件有一个压缩失败就停止压缩并返回(等价于windows上直接进行压缩)
     */
    public static boolean zipFile(String srcPath, String dstPath) {
        File srcFile = new File(srcPath);
        if (!srcFile.exists()) {
            return false;
        }
        byte[] buffer = new byte[BUFF_SIZE];
        try {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dstPath));
            boolean result = zipFile(zos, "", srcFile, buffer);
            zos.close();
            return result;
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * @param srcPath
     *            待解压的zip文件
     * @param dstPath
     *            zip解压后待存放的目录
     * @return 只要解压过程中发生错误,就立即停止并返回(等价于windows上直接进行解压)
     */
    public static boolean unzipFile(String srcPath, String dstPath) {
        if(TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(dstPath)) {
            return false;
        }
        File srcFile = new File(srcPath);
        if(!srcFile.exists() || !srcFile.getName().toLowerCase(Locale.getDefault()).endsWith("zip")) {
            return false;
        }
        File dstFile = new File(dstPath);
        if(!dstFile.exists() || !dstFile.isDirectory()) {
            dstFile.mkdirs();
        }
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream(srcFile));
            BufferedInputStream bis = new BufferedInputStream(zis);
            ZipEntry zipEntry = null;
            byte[] buffer = new byte[BUFF_SIZE];
            if(!dstPath.endsWith(File.separator)) {
                dstPath += File.separator;
            }
            while((zipEntry = zis.getNextEntry()) != null) {
                String fileName = dstPath + zipEntry.getName();
                File file = new File(fileName);
                File parentDir = file.getParentFile();
                if(!parentDir.exists()) {
                    parentDir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(file);
                while(bis.read(buffer) != -1) {
                    fos.write(buffer);
                }
                fos.close();
            }
            bis.close();
            zis.close();
            return true;
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return false;
    }

}

 

感谢评论中的这位小哥指出这个问题

InputStream 的 read 方法会尽可能地填充满这个 buffer,同时返回当前填充的长度。

(1)当快到文件末尾的时候,可能只填充了部分 buffer,所以此时就需要按读取的实际长度来操作得到的这个 buffer 了

(2)当读到文件末尾的 EOF 标志的时候会返回 -1,可以通过这个特殊标志来结束循环。

 

2019-05-06 新版的压缩代码,包括ZIP和TAR+GZIP

https://blog.csdn.net/chy555chy/article/details/89878563

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值