关于文件压缩这方面,原先的项目用的不是太多,也不是太熟悉。但是这次项目用到了,从网上的找了一些资料,仔细的研究了一番,网上各位牛人的代码确实好用,本人在根据项目的需求进行了稍微的调整,本文章只是本人的记录与学习,并非原创(后来没用上,项目功能砍掉了,只是自己的dome,随笔记录,错误希望指出来,大家一起学习)。

  1、项目开始的需求是上传用户的身份证正面,反面及手持的三张图片,要求分别压缩并上传到服务器,压缩文件

夹的名字是的13位毫秒时间戳;
  2、后来改为另三个图片放到一个文件夹中,再将文件夹压缩,压缩文件夹的名字是的13位毫秒时间戳,要求上传

到服务器;

区别就是 单张压缩上传和  三张一起压缩上传

一、这里面先说一下,单张图片压缩

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.test.xingtaibank.FileUtils.FileUtils;

import java.io.File;
import java.io.IOException;

import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2018/8/9.
 * 文件上传统一为Zip格式的压缩文件
 * 压缩文件以当前上传时间时间戳命名(精确到毫秒)
 * 压缩包内文件命名方式:
 * 关联业务申请编号_文件类型.后缀名
 * 开户场景的命名:
 * 银行卡号_文件类型.后缀名
 * 文件类型(fileType):
 * A-统一社会信用代码证;B-营业执照;C-组织机构代码证;D-法人身份证正面;E-法人身份证反面;
 */

public class BankUpFile {
    /**
     * 获取本地图片路径 ,压缩文件问.zip格式,并上传服务器
     *
     * @param custAcctNo 客户的账户号码
     * @param newPath    文件的路径
     * @param callback   上传成功的回调,返回成功的信息
     *
     *
     *                   将选择的图片重命名后,放置到一个文件,然后压缩该文件
     */
    public static void UpFileData(Context context, final String custAcctNo, final File newPath, String newName, final Callback callback) {

        
        //TODO 压缩文件以当前上传时间时间戳命名(精确到毫秒)
        final String filename = String.valueOf(BankTool.getMillisecond());
        //TODO 图片重命名
        String s = String.valueOf(newPath);
        String replace = "";
        if (s.contains("/")) {
            String[] split = s.split("/");
            String s1 = split[split.length - 1];
            String[] split1 = s1.split("[.]");
            if (s.contains(split1[0])) {
                replace = s.replace(split1[0], newName);
            }
        }
        final File replace2 = new File(replace);
        //判断文件夹是否存在,如果不存在就创建,否则不创建
        if (!replace2.exists()) {
            //通过file的mkdirs()方法创建目录中包含却不存在的文件夹
            replace2.mkdirs();
        }
        FileUtils.renameFile(String.valueOf(newPath), replace);


        //TODO 创建存储上传文件的文件夹zsbzip
        final String zsbzip = Environment.getExternalStorageDirectory().getPath() + "/00zsbzip";
        File file = new File(zsbzip);
        //判断文件夹是否存在,如果不存在就创建,否则不创建
        if (!file.exists()) {
            //通过file的mkdirs()方法创建目录中包含却不存在的文件夹
            file.mkdirs();
        }

        //TODO 存储上传文件的文件夹zsbzip.zip
        final String zsbzipSSS = zsbzip + "/" + filename + ".zip";
        //TODO 上传文件
        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    //如果压缩文件成功===>上传文件
                    if (ZipUtil.zip2(replace2, zsbzip, filename)) {
                        final OkHttpClient client = new OkHttpClient();
                        MediaType type = MediaType.parse("application/octet-stream");
                        MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
                        File file2 = new File(zsbzipSSS);
                        RequestBody fileBody = RequestBody.create(type, file2);
                        RequestBody requestBody = new MultipartBody.Builder()
                                .setType(mediaType)
                                .addPart(Headers.of("Content-Disposition", "form-data; name=\"appType\""),
                                        RequestBody.create(null, "001"))
                                .addPart(Headers.of("Content-Disposition", "form-data; name=\"custAcctNo\""),
                                        RequestBody.create(null, custAcctNo))
                                .addPart(Headers.of("Content-Disposition", "form-data; name=\"Text\""),
                                        RequestBody.create(null, "application/xml"))
                                .addPart(Headers.of("Content-Disposition", "form-data; name=\"file[0]\"; filename=\"" + zsbzipSSS + "\""),
                                        fileBody)
                                .build();
                        final Request request = new Request.Builder()
                                .url("https://scftest.xtbank.com:1443/xtscf/fileUpload.do")
                                .post(requestBody)
                                .addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
                                .addHeader("Cache-Control", "no-cache")
                                .addHeader("Postman-Token", "a04bb0f7-dcbf-435f-a782-bb79a03a7da4")
                                .build();
                        client.newCall(request).enqueue(new okhttp3.Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                callback.UpFileonFailure(e.toString());
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                String Msg = response.body().string();
                                callback.UpFileonResponse(response, Msg);
                                //客户[6222021001116245]文件上传成功,rspCode=000000\n
                                if (response.code() == 200) {//请求服务器成功
                                   
                                }
                            }
                        });

                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        th.start();
    }

    public interface Callback {

        void UpFileonFailure(String e);

        void UpFileonResponse(Response response, String bodystring);
    }
}

这是我有所写的方法

/**
     * 生成13位毫秒时间戳
     *
     * @return
     */
    public static Long getMillisecond() {
        Long time = new Date().getTime();
        return time;
    }
 /**
     * 重命名文件
     *
     * @param oldPath 原来的文件地址
     * @param newPath 新的文件地址
     */
    public static void renameFile(String oldPath, String newPath) {
        File oleFile = new File(oldPath);
        File newFile = new File(newPath);
        //执行重命名
        oleFile.renameTo(newFile);
    }

压缩的方法:

/**
     * 将文件压缩
     * @param fileOrDirectory 要压缩的文件
     * @param dest            要压缩的文件夹
     * @param name            压缩后的zip 的文件名字
     * @return
     * @throws IOException
     */

    public static boolean zip2(File fileOrDirectory, String dest, String name) throws IOException {
        int length = 0;
        int progress = 0;
        File destFile = new File(dest);//源文件或者目录
        if (!destFile.exists()) {
            try {
                destFile.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        dest = dest + "/" + name + ".zip";
        //提供了一个数据项压缩成一个ZIP归档输出流
        ZipOutputStream out = null;
        try {
            File outFile = new File(dest);//源文件或者目录
            if (!outFile.exists()) {
                try {
                    outFile.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            out = new ZipOutputStream(new FileOutputStream(outFile));
            //如果此文件是一个文件,否则为false。
            if (fileOrDirectory.isFile()) {
                zipFileOrDirectory(out, fileOrDirectory, "");
            } else {
                //返回一个文件或空阵列。
                File[] entries = fileOrDirectory.listFiles();
                length = entries.length;
                //TODO 监听长度 是否走完
                for (int i = 0; i < entries.length; i++) {
                    // 递归压缩,更新curPaths
                    zipFileOrDirectory(out, entries[i], "");
                    progress = i + 1;
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            //关闭输出流
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        if (progress == length) {
            Log.e("MMM", "zipFileOrDirectory: 压缩完成");
            return true;
        }
        return false;
    }

二)多张图片压缩到文件中

从相册或者拍照,获取图片的路径,再将图片裁剪压缩后,防止到自己新建的文件夹中(文件夹中一张图或者多张图片),再将文件夹压缩为,时间戳命名的zip文件,上传该文件

//获取相册 或者拍照  返回的图片的路径的集合 
ArrayList<String> imagesResult = data.getStringArrayListExtra("takeSuccess");
        final String path = imagesResult.get(0);//获取到本地路径

     

        //TODO 1)将本地图片裁剪,2)修改名字,3)放置到以时间戳命名的文件夹中,4)将放置图片的文件夹压缩为zip文件
        //TODO 1)将本地图片裁剪
        final File newPath = CompressHelper.getDefault(getApplicationContext()).compressToFile(new File(path));//裁剪后的图片文件
        //TODO 2)图片重命名
        String s = String.valueOf(newPath);
        String replace = "";
        if (s.contains("/")) {
            String[] split = s.split("/");
            String s1 = split[split.length - 1];
            String[] split1 = s1.split("[.]");
            if (s.contains(split1[0])) {
                replace = s.replace(split1[0], PhotoName);
            }
        }
        final File replace2 = new File(replace);
        FileUtils.renameFile(String.valueOf(newPath), replace);
        //TODO 3)放置到以时间戳命名的文件夹中(精确到毫秒)
        final String MillisecondName = String.valueOf(BankTool.getMillisecond());//时间戳 压缩的文件的名字
        if (replace2.exists()) {
            filemap.put(PhotoName, replace2);
        }
        final String zsbzip = Environment.getExternalStorageDirectory().getPath() + "/" + "0zsb_xt";//选择图片并裁剪过的图片存放的文件夹
        final String zsbzip2 = Environment.getExternalStorageDirectory().getPath() + "/" + "0zsb_xtzip";//压缩后的文件。存放的路径
        File file2 = new File(zsbzip2);
        //判断文件夹是否存在,如果不存在就创建,否则不创建
        if (!file2.exists()) {
            //通过file的mkdirs()方法创建目录中包含却不存在的文件夹
            file2.mkdirs();
        }
        File file = new File(zsbzip);
        //判断文件夹是否存在,如果不存在就创建,否则不创建
        if (!file.exists()) {
            //通过file的mkdirs()方法创建目录中包含却不存在的文件夹
            file.mkdirs();
        }
        BankTool.copy(replace, zsbzip);
       //上传的zip文件
        final String Updatazip = Environment.getExternalStorageDirectory().getPath() + "/" + "0zsb_xtzip" + "/" + MillisecondName + ".zip";
        //TODO 4)将放置图片的文件夹压缩为zip文件
        /**
         * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
         * @param sourceFilePath    :待压缩的文件路径
         * @param zipFilePath       :压缩后存放路径
         * @param fileName          :压缩后文件的名称
         * @return
         */
        upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean b = FileToZip.fileToZip(zsbzip, zsbzip2, MillisecondName);
                if (b) {
                    Toast.makeText(context, "压缩完成", Toast.LENGTH_SHORT).show();
                    BankUpFile2.UpFileData(context, Updatazip, "6222021001116245", new BankUpFile2.Callback() {
                        @Override
                        public void UpFileonFailure(String e) {
                            
                        }

                        @Override
                        public void UpFileonResponse(Response response, String bodystring) {

                        }
                    });
                }

            }
        });

压缩方法为:

package com.test.xingtaibank.FileUtils;

import java.io.BufferedInputStream;
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.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by Administrator on 2018/8/18.
 * 将文件夹压缩
 */

public class FileToZip {
    private FileToZip(){}

    /**
     * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
     * @param sourceFilePath :待压缩的文件路径
     * @param zipFilePath :压缩后存放路径
     * @param fileName :压缩后文件的名称
     * @return
     */
    public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName){
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;

        if(sourceFile.exists() == false){
            System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在.");
        }else{
            try {
                File zipFile = new File(zipFilePath + "/" + fileName +".zip");
                if(zipFile.exists()){
                    System.out.println(zipFilePath + "目录下存在名字为:" + fileName +".zip" +"打包文件.");
                }else{
                    File[] sourceFiles = sourceFile.listFiles();
                    if(null == sourceFiles || sourceFiles.length<1){
                        System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
                    }else{
                        fos = new FileOutputStream(zipFile);
                        zos = new ZipOutputStream(new BufferedOutputStream(fos));
                        byte[] bufs = new byte[1024*10];
                        for(int i=0;i<sourceFiles.length;i++){
                            //创建ZIP实体,并添加进压缩包
                            ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                            zos.putNextEntry(zipEntry);
                            //读取待压缩的文件并写进压缩包里
                            fis = new FileInputStream(sourceFiles[i]);
                            bis = new BufferedInputStream(fis, 1024*10);
                            int read = 0;
                            while((read=bis.read(bufs, 0, 1024*10)) != -1){
                                zos.write(bufs,0,read);
                            }
                        }
                        flag = true;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally{
                //关闭流
                try {
                    if(null != bis) bis.close();
                    if(null != zos) zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }
        return flag;
    }
}

将图片文件复制到其他文件夹的方法是:

/**
     *
     * @param file1  需要复制的文件的路径
     * @param file2  复制后的文件放置的文件夹路径
     */
    public static void copy(String file1, String file2) {
        System.out.println(file1);
        System.out.println(file2);
        File src = new File(file1);
        File dst = new File(file2);
        if (!dst.exists()) {
            dst.mkdirs();
        }
        InputStream in = null;
        OutputStream out = null;
        //System.out.println(file1.substring(file1.lastIndexOf("/"),file1.length()));//获取单个文件的源文件的名称
        try {
            in = new BufferedInputStream(new FileInputStream(src), 16 * 1024);
            FileOutputStream f = new FileOutputStream(dst + file1.substring(file1.lastIndexOf("/"), file1.length()));//一定要加上文件名称
            out = new BufferedOutputStream(f, 16 * 1024);
            byte[] buffer = new byte[16 * 1024];
            int len = 0;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

最后上传zip文件:

package com.test.xingtaibank;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.widget.Toast;

import com.test.xingtaibank.FileUtils.FileUtils;

import java.io.File;
import java.io.IOException;

import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2018/8/9.
 * 文件上传统一为Zip格式的压缩文件
 * 压缩文件以当前上传时间时间戳命名(精确到毫秒)
 * 压缩包内文件命名方式:
 * 关联业务申请编号_文件类型.后缀名
 * 开户场景的命名:
 * 银行卡号_文件类型.后缀名
 * 文件类型(fileType):
 * A-统一社会信用代码证;B-营业执照;C-组织机构代码证;D-法人身份证正面;E-法人身份证反面;
 */

public class BankUpFile2 {
    /**
     * 获取本地图片路径 ,压缩文件问.zip格式,并上传服务器
     *
     * @param custAcctNo 客户的账户号码
     * @param upFilePath 文件的路径
     * @param callback   上传成功的回调,返回成功的信息
     */
    public static void UpFileData(Context context, final String upFilePath, final String custAcctNo, final Callback callback) {

        //TODO 上传文件
        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                final OkHttpClient client = new OkHttpClient();
                MediaType type = MediaType.parse("application/octet-stream");
                MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
                File file2 = new File(upFilePath);
                RequestBody fileBody = RequestBody.create(type, file2);
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(mediaType)
                        .addPart(Headers.of("Content-Disposition", "form-data; name=\"appType\""),
                                RequestBody.create(null, "001"))
                        .addPart(Headers.of("Content-Disposition", "form-data; name=\"custAcctNo\""),
                                RequestBody.create(null, custAcctNo))
                        .addPart(Headers.of("Content-Disposition", "form-data; name=\"Text\""),
                                RequestBody.create(null, "application/xml"))
                        .addPart(Headers.of("Content-Disposition", "form-data; name=\"file[0]\"; filename=\"" + upFilePath + "\""),
                                fileBody)
                        .build();
                final Request request = new Request.Builder()
                        .url("https://scftest.xtbank.com:1443/xtscf/fileUpload.do")
                        .post(requestBody)
                        .addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
                        .addHeader("Cache-Control", "no-cache")
                        .addHeader("Postman-Token", "a04bb0f7-dcbf-435f-a782-bb79a03a7da4")
                        .build();
                client.newCall(request).enqueue(new okhttp3.Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        callback.UpFileonFailure(e.toString());
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        String Msg = response.body().string();
                        callback.UpFileonResponse(response, Msg);
                        //客户[6222021001116245]文件上传成功,rspCode=000000\n
                        if (response.code() == 200) {//请求服务器成功

                        }
                    }
                });

            }
        });
        th.start();
    }

    public interface Callback {

        void UpFileonFailure(String e);

        void UpFileonResponse(Response response, String bodystring);
    }
}