zip解压线程(解决中文问题)

Posted xhzxlqt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zip解压线程(解决中文问题)相关的知识,希望对你有一定的参考价值。

准备工作

android自带的zip解压不能处理中文文件名,需要引用第三方jar

apache的commons-compress 1.12

http://central.maven.org/maven2/org/apache/commons/commons-compress/1.12/commons-compress-1.12.jar

下载下来,放到app的libs目录

as转换到project视图

技术分享图片

右击那个jar

技术分享图片

然后:

技术分享图片

就会在build.gradle(module:app)自动添加:

implementation files(‘libs/commons-compress-1.12.jar‘)

解压线程

技术分享图片
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.RawRes;
import android.util.Log;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.zip.ZipEntry;


/*
* @author [email protected]
* create at 2018/6/12
* description:zip解压线程
*/
public class LeesUnzipThread extends AsyncTask<String,Integer,Integer> {
    String TAG="LeesUnzipThread";
    ProgressDialog  progressDialog=null;
    RoundProgressBar roundProgressBar=null;
    String strZipFile=null;
    int srcType=0;
    int resID=-1;//资源ID
    Context mContext=null;

    public LeesUnzipThread(@NonNull String zipFile,ProgressDialog dlg){
        strZipFile=zipFile;
        progressDialog=dlg;
        srcType=0;
    }

    public LeesUnzipThread(@NonNull String zipFile,RoundProgressBar roundProgressBar){
        strZipFile=zipFile;
        this.roundProgressBar=roundProgressBar;
        srcType=0;
    }

    public LeesUnzipThread(@RawRes int srcID,@NonNull Context context,ProgressDialog dlg){
        resID=srcID;
        mContext=context;
        progressDialog=dlg;
        srcType=1;
    }

    public LeesUnzipThread(@RawRes int srcID,@NonNull Context context,RoundProgressBar roundProgressBar){
        resID=srcID;
        mContext=context;
        this.roundProgressBar=roundProgressBar;
        srcType=1;
    }

    private int getZipFileCount(@NonNull InputStream is){
        int nFileCount=0;
        ZipArchiveInputStream zis=new ZipArchiveInputStream(is,"GBK");

        ArchiveEntry ae=null;
        ZipEntry ze=null;
        try {
            while ((ze =(ZipEntry) zis.getNextEntry()) != null) {
                if (!ze.isDirectory()) {
                    nFileCount++;
                }
            }
        }catch (IOException e){
            Log.e(TAG,e.getMessage());
        }finally {
            try{
                if(zis!=null){
                    zis.close();
                }
            }catch (IOException e){
                Log.e(TAG,e.getMessage());
            }
        }
        return nFileCount;
    }

    /*
    * 函数功能:获取压缩包中文件(不含目录)的数量
    * Author: [email protected]
    * Create: 2018/6/12 22:32
    */
    public int getFileCount() {
        InputStream is = null;
        int nFileCount = 0;//压缩文档中文件数量
        if(srcType==1){//res.raw下的zip文档
            Resources resources=mContext.getResources();
            is = resources.openRawResource(resID);
        }else if(srcType==0){//普通路径下的zip文档
            File file = new File(strZipFile);
            try {
                if(!file.exists()){
                    throw new IOException("File "+ strZipFile +"not exist!");
                }
                is = new FileInputStream(file);
            }catch (IOException e){
                Log.e(TAG,e.getMessage());
            }
        }

        if(is!=null){
            nFileCount=getZipFileCount(is);
            try {
                is.close();
            }catch (IOException e){
                nFileCount=0;
                Log.e(TAG,e.getMessage());
            }
        }

        return nFileCount;
    }

    private void unZipToFolder(@NonNull String strDestFolder){
        Log.i("unZipResZip: ","strDestFolder:	"+ strDestFolder);
        if(!strDestFolder.endsWith("\\") && !strDestFolder.endsWith("/") ){
            strDestFolder += File.separator;
        }

        File dir = new File(strDestFolder);
        if(!dir.exists()){
            dir.mkdirs();
        }

        int BUFFER = 4096; //这里缓冲区我们使用4KB,
        InputStream is = null;
        int nFileCounter = 0;//解压计数(不含目录)
        //region 准备InputStream
        if(srcType==1){//res.raw下的zip文档
            Resources resources=mContext.getResources();
            is = resources.openRawResource(resID);
        }else if(srcType==0){//普通路径下的zip文档
            File file = new File(strZipFile);
            try {
                if(!file.exists()){
                    throw new IOException("File "+ strZipFile +"not exist!");
                }
                is = new FileInputStream(file);
            }catch (IOException e){
                Log.e(TAG,e.getMessage());
            }
        }
        //endregion

        if(is!=null){
            //region 解压缩
            ZipArchiveInputStream zis=new ZipArchiveInputStream(is,"GBK");
            ArchiveEntry ae=null;
            try {
                while ((ae = zis.getNextEntry()) != null) {
                    // 获取文件名
                    String entryFileName = ae.getName();
                    // 解压目标文件全路径
                    String strDstFullPath = strDestFolder + entryFileName;
                    if (ae.isDirectory()) {
                        File folder = new File(strDstFullPath);
                        if(!folder.exists()){
                            folder.mkdirs();
                        }
                        continue;
                    }
                    OutputStream os=new BufferedOutputStream(new FileOutputStream(strDstFullPath));
                    byte[] buf = new byte[1024 ];
                    int len = -1;
                    while((len = zis.read(buf)) != -1) {
                        os.write(buf, 0, len);
                    }
                    os.flush();
                    os.close();
                    nFileCounter++;
                    publishProgress(nFileCounter);
                }
            }catch (IOException e){
                Log.e(TAG,e.getMessage());
            }finally {
                try{
                    if(zis!=null){
                        zis.close();
                    }
                }catch (IOException e){
                    Log.e(TAG,e.getMessage());
                }
            }
            //endregion
            try {
                is.close();
            }catch (IOException e){
                Log.e(TAG,e.getMessage());
            }
        }

    }
    @Override
    protected Integer doInBackground(String... strings) {
        //region 参数校验
        String strDestFolder=strings[0];

        if(strDestFolder==null){
            try {
                throw new FileNotFoundException("dest folder if null");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
        //endregion
        unZipToFolder(strDestFolder);
        return null;
    }


    @Override
    protected void onProgressUpdate(Integer... progress){
        super.onProgressUpdate(progress);
        if(progressDialog!=null){
            progressDialog.setProgress(progress[0]);
        }
        else if(roundProgressBar!=null){
            roundProgressBar.setProgress(progress[0]);
        }
    }
}
View Code

调用示例

PermissionUtil.verifyStoragePermissions(this);

       //RoundProgressBar为自定义圆形进度
        mRoundProgressBar=(RoundProgressBar)findViewById(R.id.rpb_unzip);

       //raw下zip  内含中文目录
        LeesUnzipThread unzipThread=new LeesUnzipThread(R.raw.dlsw,getBaseContext(),mRoundProgressBar);
//sdcard/download目录下zip 内含中文目录 // LeesUnzipThread unzipThread=new LeesUnzipThread("/storage/emulated/0/download/dlsw.zip",mRoundProgressBar); int nFileCount=unzipThread.getFileCount(); if(nFileCount>0){ mRoundProgressBar.setMax(nFileCount);
//开始解压到目标文件夹 unzipThread.execute(
"/storage/emulated/0/dlshouwen/"); }

 

以上是关于zip解压线程(解决中文问题)的主要内容,如果未能解决你的问题,请参考以下文章

请大神帮忙解决一个用java解压缩一个zip压缩格式字节流中文内容乱码问题!

解决 centos下附件 zip文件解压乱码问题

Linux系统解压Mac发送过来的zip文件出现中文乱码问题解决

Linux系统解压Mac发送过来的zip文件出现中文乱码问题解决

Linux系统解压Mac发送过来的zip文件出现中文乱码问题解决

java压缩中文zip,系统winrar解压改中文zip会出现乱码