Android开发之Zip下载解压

本篇博客为需求而发烧,若有雷同需求code拿走不谢。


需求如下:点击Item,从服务器下载zip包到本地文件夹并解压,解压后的图片文件全部查询出来,用于界面预览

没有强制每次都下载zip包保持最新,如果有需要FileDownload有函数支持,亦可以自行添加解压后自动删除zip包

流程:

  • 下载zip包

  • 解压zip包

  • 查询指定文件格式的文件路径集合(.jpg为例)

文件下载推荐开源库FileDownloader

https://github.com/lingochamp/FileDownloader

compile 'com.liulishuo.filedownloader:library:1.7.2'

接入项目首先Application初始化

FileDownloader.setup(Context)

需求是单任务下载zip,调用示例如下

FileDownloader.getImpl().create(url)
        .setPath(path)
        .setListener(new FileDownloadListener() {
            @Override
            protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void blockComplete(BaseDownloadTask task) {
            }

            @Override
            protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
            }

            @Override
            protected void completed(BaseDownloadTask task) {
            }

            @Override
            protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void error(BaseDownloadTask task, Throwable e) {
            }

            @Override
            protected void warn(BaseDownloadTask task) {
            }
        }).start();

是否支持强制重新下载zip包

 setForceReDownload(false)

文件下载完成后开始解压,这里推荐使用开源库zt-zip

https://github.com/zeroturnaround/zt-zip

解压zip但不需要过滤匹配是否含有指定文件,所以只需要传入文件路径和解压目录

 private void unPackage(String zipPath,String outputDir){
        ZipUtil.unpack(new File(zipPath), new File(outputDir));
    }

解压后遍解压目录下的.jpg文件

    /**
     * 查询解压目录下的文件,并过滤文件格式返回路径集合
     * @hide
     * @param outputDir
     * @return
     */
    private ArrayList queryUnPackageOutputDir(String outputDir){
            ArrayList arrayList = new ArrayList<>();
            File file = new File(outputDir);
            File[] subFile = file.listFiles();
            for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
                if (!subFile[iFileLength].isDirectory()) {
                    String filename = subFile[iFileLength].getAbsolutePath();
                    if (filename.trim().toLowerCase().endsWith(".jpg")) {
                        arrayList.add(filename);
                    }
                }
            }
            return arrayList;
    }

下面提供一个Helper类以及代码调用示例

import android.app.Activity;
import android.os.Environment;
import android.util.Log;

import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;

import org.zeroturnaround.zip.ZipUtil;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by idea on 2018/3/26.
 */

public class ZipHelper {

    public static final String TEST_ZIP_URL = "用于测试的zip下载地址,自行完善";

    /***
     *
     * Unpacking
     *
     * Check if an entry exists in a ZIP archive
     * boolean exists = ZipUtil.containsEntry(new File("/tmp/demo.zip"), "foo.txt");
     *
     * Extract an entry from a ZIP archive into a byte array
     * byte[] bytes = ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt");
     *
     * Extract an entry from a ZIP archive with a specific Charset into a byte array
     * byte[] bytes = ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt", Charset.forName("IBM437"));
     *
     * Extract an entry from a ZIP archive into file system
     * ZipUtil.unpackEntry(new File("/tmp/demo.zip"), "foo.txt", new File("/tmp/bar.txt"));
     *
     * Extract a ZIP archive
     * ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"));
     *
     * Extract a ZIP archive which becomes a directory
     * ZipUtil.explode(new File("/tmp/demo.zip"));
     *
     * Extract a directory from a ZIP archive including the directory name
     * ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
     *          public String map(String name) {
     *              return name.startsWith("doc/") ? name : null;
     *          }
     *  });
     *
     * Extract a directory from a ZIP archive excluding the directory name
     * final String prefix = "doc/";
     * ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
     *    public String map(String name) {
     *      return name.startsWith(prefix) ? name.substring(prefix.length()) : name;
     *    }
     * });
     *
     * Extract files from a ZIP archive that match a name pattern
     *
     * ZipUtil.unpack(new File("/tmp/demo.zip"), new File("/tmp/demo"), new NameMapper() {
     *    public String map(String name) {
     *          if (name.contains("/doc")) {
     *             return name;
     *          }else {
     *             // returning null from the map method will disregard the entry
     *             return null;
     *          }
     *    }
     * });
     *
     * Print .class entry names in a ZIP archive
     * ZipUtil.iterate(new File("/tmp/demo.zip"), new ZipInfoCallback() {
     *        public void process(ZipEntry zipEntry) throws IOException {
     *             if (zipEntry.getName().endsWith(".class"))
     *                 System.out.println("Found " + zipEntry.getName());
     *              }
     * });
     *
     * Print .txt entries in a ZIP archive (uses IoUtils from Commons IO)
     * ZipUtil.iterate(new File("/tmp/demo.zip"), new ZipEntryCallback() {
     *            public void process(InputStream in, ZipEntry zipEntry) throws IOException {
     *                  if (zipEntry.getName().endsWith(".txt")) {
     *                     System.out.println("Found " + zipEntry.getName());
     *                     IOUtils.copy(in, System.out);
     *                  }
     *            }
     * });
     *
     *  @hide
     * 解压zip文件
     *
     */
    private void unPackage(String zipPath,String outputDir){
        ZipUtil.unpack(new File(zipPath), new File(outputDir));
    }

    /**
     * 查询解压目录下的文件,并过滤文件格式返回路径集合
     * @hide
     * @param outputDir
     * @return
     */
    private ArrayList queryUnPackageOutputDir(String outputDir){
            ArrayList arrayList = new ArrayList<>();
            File file = new File(outputDir);
            File[] subFile = file.listFiles();
            for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
                if (!subFile[iFileLength].isDirectory()) {
                    String filename = subFile[iFileLength].getAbsolutePath();
                    if (filename.trim().toLowerCase().endsWith(".jpg")) {
                        arrayList.add(filename);
                    }
                }
            }
            return arrayList;
    }

    /**
     * 判断指定目录是否下载过zip文件
     * @param zipName zip文件名称
     * @param zipCachePath 文件夹
     * @hide
     * @return
     */
    private boolean containsZipFile(String zipCachePath,String zipName){
        boolean result = false;
        File file = new File(zipCachePath);
        if (file.exists()) {
            File zipFile = new File(zipCachePath+"/"+zipName);
            if(zipFile.exists()){
                result = true;
            } else{
                result = false;
            }
        } else {
            file.mkdir();
        }
        return result;
    }

    /**
     * 下载zip文件
     * @hide
     * @param url
     * @param zipPath
     */
    private void downloadZipFile(String url, String zipPath,final OnDownloadZipListener onDownloadZipListener){
        FileDownloader.getImpl().create(url)
                .setPath(zipPath)
                .setForceReDownload(false)
                .setListener(new FileDownloadListener() {
                    @Override
                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void blockComplete(BaseDownloadTask task) {
                    }

                    @Override
                    protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
                    }

                    @Override
                    protected void completed(BaseDownloadTask task) {
                        onDownloadZipListener.onComplete();
                    }

                    @Override
                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                    }

                    @Override
                    protected void error(BaseDownloadTask task, Throwable e) {
                        onDownloadZipListener.onError();
                    }

                    @Override
                    protected void warn(BaseDownloadTask task) {
                    }
                }).start();
    }

    /**
     * 每加载完成一张图片就立即删除文件
     * @param path
     */
    public void deleteFile(String path){
        File file = new File(path);
        if(file.isFile()&&file.exists()){
            file.delete();
        }
    }

    /**
     * 刪除解压文件
     */
    public void clearOutputDir(){
        String dir = "/iot.monitoring.zip.output";
        File outputDirFile = new File(Environment.getExternalStorageDirectory(), dir);
            File[] listFiles = outputDirFile.listFiles();
            if (outputDirFile.exists()&&listFiles!=null&&listFiles.length>0) {
                for(int i = 0;i/**
     * 下载zip文件
     * @hide
     * @param url 下载路径
     * @param zipCachePath 缓存目录
     * @param outputDir 解压目录
     */
    private void doBackground(final Activity activity, final String url, final String zipCachePath, final String outputDir, final UnPackageImageListener unPackageImageListener){

                //阿里云 zip下路路径格式如下: http//xxxxxx.xx.xx/xxx/xxx.zip?xxxxxx
                int index = url.indexOf("?");
                final String [] array = url.substring(0,index).split("/");
                downloadZipFile(url, zipCachePath + "/" + array[array.length - 1], new OnDownloadZipListener() {
                    @Override
                    public void onError() {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                unPackageImageListener.onError();
                            }
                        });
                    }

                    @Override
                    public void onComplete() {
                        unPackage(zipCachePath+"/"+array[array.length-1],outputDir);
                        final ArrayList collection = queryUnPackageOutputDir(outputDir);
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                unPackageImageListener.onSuccess(collection);
                            }
                        });
                    }
                });

    }

    /**
     * 下载zip图片集合并解压到目录,获取查询结果
     * @param activity
     * @param url
     * @param unPackageImageListener
     */
    public void queryImageCollection(final Activity activity, final String url, final UnPackageImageListener unPackageImageListener){

        String dir = "/idea.analyzesystem.zip";
        File zipCachePathDir = new File(Environment.getExternalStorageDirectory(), dir);
        if (!zipCachePathDir.exists()) {
            zipCachePathDir.mkdir();
        }
        dir = "/idea.analyzesystem.zip.output";
        File outputDir = new File(Environment.getExternalStorageDirectory(), dir);
        if (!outputDir.exists()) {
            outputDir.mkdir();
        }

        clearOutputDir();

        String zipCachePath = zipCachePathDir.getAbsolutePath();
        String outputDirPath = outputDir.getAbsolutePath();
        doBackground(activity,url,zipCachePath,outputDirPath,unPackageImageListener);

    }

    public interface OnDownloadZipListener{
        void onError();

        void onComplete();
    }

    public interface UnPackageImageListener{
        void onError();

        void onSuccess(ArrayList result);
    }

}

 new ZipHelper().queryImageCollection(getActivity(),url,new ZipHelper.UnPackageImageListener() {

         @Override
         public void onError() {

         }

         @Override
         public void onSuccess(ArrayList result) {

         }
   });

你可能感兴趣的:(Android)