关闭

打包上传zip文件

1237人阅读 评论(0) 收藏 举报
分类:

最近项目需求将图片打包成zip上传, 记录一下。

为了方便以后使用就把它写成工具类的形式吧。这里一共用到3个工具类

分别是XZip(用于压缩)、UploadUtils(文件上传类)、

ThreadPoolUtils(线程池)

一、用法

/**
 * 
 * 应用运行前提:SD卡中放置任务文件夹(两层,第一层/mnt/sdcard/FolderZipSend/task/,
 * 第二层/mnt/sdcard/FolderZipSend/task/meter1、meter2,每个子文件夹里放几幅图片)
 * 执行过程中首先将task目录整体打包为sendfile.zip,然后上传至指定服务器接口
 * 
 * @author li
 *
 */
@SuppressLint({ "SdCardPath", "HandlerLeak" })
public class MainActivity extends Activity {

    private Button zipsendBtn;
    private ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        zipsendBtn = (Button) findViewById(R.id.button1);
        zipsendBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                progressDialog = ProgressDialog.show(MainActivity.this, "压缩上传中", "请稍候");
                ThreadPoolUtils.execute(runnable);
            }
        });
    }

    /**
     * 压缩及上传操作
     */
    Runnable runnable = new Runnable(){
        @Override
        public void run() {
            String message = "";
            message = zipAndSend();
            Message msg = new Message();
            msg.what = 0;
            msg.obj = message;
            handler1.sendMessage(msg);
        }};

    Handler handler1 = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            progressDialog.dismiss();
            Toast.makeText(getApplicationContext(), (String)msg.obj,Toast.LENGTH_SHORT).show();
        }
    };

    private String zipAndSend(){

        File zipfile = new File(Environment.getExternalStorageDirectory()+"/Photo_ies/", "Photo_ies.zip");
        if(!zipfile.exists()) {
            try {
                zipfile.createNewFile();
            } catch (IOException e1) {
                e1.printStackTrace();
                return "压缩包创建出错";
            }
        }

        try {
            XZip.ZipFolder(Environment.getExternalStorageDirectory()+"/Photo_ies/",
                    Environment.getExternalStorageDirectory()+"/Photo_ies/"+"sendfile.zip");
        } catch (Exception e) {
            e.printStackTrace();
            return "压缩出错";
        }

        // TODO 暂定链接,本例中在这个php文件内实现文件接收并指定服务端存储目录
        if (null == UploadUtil.uploadFile(zipfile, "http://10.101.126.38/receive.php")) {
            return "发送出错";
        }

//      zipfile.delete();// 删除已发送的包
        return "执行成功";
    }
}

二、工具类

1. XZip

/**
 * Android Zip压缩解压缩
 * 
 * @author li
 * @version 1.0
 * 
 */

public class XZip {

    public XZip() {

    }

    /**
     * 取得压缩包中的 文件列表(文件夹,文件自选)
     * 
     * @param zipFileString
     *            压缩包名字
     * @param bContainFolder
     *            是否包括 文件夹
     * @param bContainFile
     *            是否包括 文件
     * @return
     * @throws Exception
     */
    public static java.util.List<java.io.File> GetFileList(
            String zipFileString, boolean bContainFolder, boolean bContainFile)
            throws Exception {

        android.util.Log.v("XZip", "GetFileList(String)");

        java.util.List<java.io.File> fileList = new java.util.ArrayList<java.io.File>();
        java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(
                new java.io.FileInputStream(zipFileString));
        java.util.zip.ZipEntry zipEntry;
        String szName = "";

        while ((zipEntry = inZip.getNextEntry()) != null) {
            szName = zipEntry.getName();

            if (zipEntry.isDirectory()) {

                // get the folder name of the widget
                szName = szName.substring(0, szName.length() - 1);
                java.io.File folder = new java.io.File(szName);
                if (bContainFolder) {
                    fileList.add(folder);
                }

            } else {
                java.io.File file = new java.io.File(szName);
                if (bContainFile) {
                    fileList.add(file);
                }
            }
        }// end of while

        inZip.close();

        return fileList;
    }

    /**
     * 返回压缩包中的文件InputStream
     * 
     * @param zipFileString
     *            压缩文件的名字
     * @param fileString
     *            解压文件的名字
     * @return InputStream
     * @throws Exception
     */
    public static java.io.InputStream UpZip(String zipFileString,
            String fileString) throws Exception {
        android.util.Log.v("XZip", "UpZip(String, String)");
        java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(zipFileString);
        java.util.zip.ZipEntry zipEntry = zipFile.getEntry(fileString);

        return zipFile.getInputStream(zipEntry);

    }

    /**
     * 解压一个压缩文档 到指定位置
     * 
     * @param zipFileString
     *            压缩包的名字
     * @param outPathString
     *            指定的路径
     * @throws Exception
     */
    public static void UnZipFolder(String zipFileString, String outPathString)
            throws Exception {
        android.util.Log.v("XZip", "UnZipFolder(String, String)");
        java.util.zip.ZipInputStream inZip = new java.util.zip.ZipInputStream(
                new java.io.FileInputStream(zipFileString));
        java.util.zip.ZipEntry zipEntry;
        String szName = "";

        while ((zipEntry = inZip.getNextEntry()) != null) {
            szName = zipEntry.getName();

            if (zipEntry.isDirectory()) {

                // get the folder name of the widget
                szName = szName.substring(0, szName.length() - 1);
                java.io.File folder = new java.io.File(outPathString
                        + java.io.File.separator + szName);
                folder.mkdirs();

            } else {

                java.io.File file = new java.io.File(outPathString
                        + java.io.File.separator + szName);
                file.createNewFile();
                // get the output stream of the file
                java.io.FileOutputStream out = new java.io.FileOutputStream(
                        file);
                int len;
                byte[] buffer = new byte[1024];
                // read (len) bytes into buffer
                while ((len = inZip.read(buffer)) != -1) {
                    // write (len) byte from buffer at the position 0
                    out.write(buffer, 0, len);
                    out.flush();
                }
                out.close();
            }
        }// end of while

        inZip.close();

    }// end of func

    /**
     * 压缩文件,文件夹
     * 
     * @param srcFileString
     *            要压缩的文件/文件夹名字
     * @param zipFileString
     *            指定压缩的目的和名字
     * @throws Exception
     */
    public static void ZipFolder(String srcFileString, String zipFileString)
            throws Exception {
        android.util.Log.v("XZip", "ZipFolder(String, String)");

        // 创建Zip包
        java.util.zip.ZipOutputStream outZip = new java.util.zip.ZipOutputStream(
                new java.io.FileOutputStream(zipFileString));

        // 打开要输出的文件
        java.io.File file = new java.io.File(srcFileString);

        // 压缩
        ZipFiles(file.getParent() + java.io.File.separator, file.getName(),
                outZip);

        // 完成,关闭
        outZip.finish();
        outZip.close();

    }// end of func

    /**
     * 压缩文件
     * 
     * @param folderString
     * @param fileString
     * @param zipOutputSteam
     * @throws Exception
     */
    private static void ZipFiles(String folderString, String fileString,
            java.util.zip.ZipOutputStream zipOutputSteam) throws Exception {
        android.util.Log.v("XZip", "ZipFiles(String, String, ZipOutputStream)");

        if (zipOutputSteam == null)
            return;

        java.io.File file = new java.io.File(folderString + fileString);

        // 判断是不是文件
        if (file.isFile()) {

            java.util.zip.ZipEntry zipEntry = new java.util.zip.ZipEntry(
                    fileString);
            java.io.FileInputStream inputStream = new java.io.FileInputStream(
                    file);
            zipOutputSteam.putNextEntry(zipEntry);

            int len;
            byte[] buffer = new byte[4096];

            while ((len = inputStream.read(buffer)) != -1) {
                zipOutputSteam.write(buffer, 0, len);
            }

            zipOutputSteam.closeEntry();
        } else {

            // 文件夹的方式,获取文件夹下的子文件
            String fileList[] = file.list();

            // 如果没有子文件, 则添加进去即可
            if (fileList.length <= 0) {
                java.util.zip.ZipEntry zipEntry = new java.util.zip.ZipEntry(
                        fileString + java.io.File.separator);
                zipOutputSteam.putNextEntry(zipEntry);
                zipOutputSteam.closeEntry();
            }

            // 如果有子文件, 遍历子文件
            for (int i = 0; i < fileList.length; i++) {
                ZipFiles(folderString, fileString + java.io.File.separator
                        + fileList[i], zipOutputSteam);
            }// end of for

        }// end of if

    }// end of func

    public void finalize() throws Throwable {

    }

}

2.UploadUtils

/**
 * 文件上传工具类
 * @author Li
 *
 */
public class UploadUtil {
    private static final String TAG = "uploadFile";
    private static final int TIME_OUT = 10*1000;   //超时时间
    private static final String CHARSET = "utf-8"; //设置编码
    /**
     * android上传文件到服务器
     * @param file  需要上传的文件
     * @param RequestURL  请求的rul
     * @return  返回响应的内容
     */
    public static String uploadFile(File file,String RequestURL)
    {
        String result = null;
        String  BOUNDARY =  UUID.randomUUID().toString();  //边界标识   随机生成
        String PREFIX = "--" , LINE_END = "\r\n"; 
        String CONTENT_TYPE = "multipart/form-data";   //内容类型

        try {
            URL url = new URL(RequestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(TIME_OUT);
            conn.setConnectTimeout(TIME_OUT);
            conn.setDoInput(true);  //允许输入流
            conn.setDoOutput(true); //允许输出流
            conn.setUseCaches(false);  //不允许使用缓存
            conn.setRequestMethod("POST");  //请求方式
            conn.setRequestProperty("Charset", CHARSET);  //设置编码
            conn.setRequestProperty("connection", "keep-alive");   
            conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); 

            if(file!=null)
            {
                /**
                 * 当文件不为空,把文件包装并且上传
                 */
                DataOutputStream dos = new DataOutputStream( conn.getOutputStream());
                StringBuffer sb = new StringBuffer();
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINE_END);
                /**
                 * 这里重点注意:
                 * name里面的值为服务器端需要key   只有这个key 才可以得到对应的文件
                 * filename是文件的名字,包含后缀名的   比如:abc.png  
                 */

                sb.append("Content-Disposition: form-data; name=\"zipfile\"; filename=\""+file.getName()+"\""+LINE_END); 
                sb.append("Content-Type: application/octet-stream; charset="+CHARSET+LINE_END);
                sb.append(LINE_END);
                dos.write(sb.toString().getBytes());
                InputStream is = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int len = 0;
                while((len=is.read(bytes))!=-1)
                {
                    dos.write(bytes, 0, len);
                }
                is.close();
                dos.write(LINE_END.getBytes());
                byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
                dos.write(end_data);
                dos.flush();
                /**
                 * 获取响应码  200=成功
                 * 当响应成功,获取响应的流  
                 */
                int res = conn.getResponseCode();  
                Log.e(TAG, "response code:"+res);
//                if(res==200)
//                {
                    Log.e(TAG, "request success");
                    InputStream input =  conn.getInputStream();
                    StringBuffer sb1= new StringBuffer();
                    int ss ;
                    while((ss=input.read())!=-1)
                    {
                        sb1.append((char)ss);
                    }
                    result = sb1.toString();
                    Log.e(TAG, "result : "+ result);
//                }
//                else{
//                    Log.e(TAG, "request error");
//                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

3.ThreadPoolUtils

package com.wayne.folderzipsend;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolUtils {
    private ThreadPoolUtils(){

    }

    //线程池核心线程数
    private static int CORE_POOL_SIZE = 5;

    //线程池最大线程数
    private static int MAX_POOL_SIZE = 10;

    //额外线程空状态生存时间
    private static int KEEP_ALIVE_TIME = 10000;

    //阻塞队列。当核心线程都被占用,且阻塞队列已满的情况下,才会开启额外线程。
    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(
            10);

    //线程工厂
    private static ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };

    //线程池
    private static ThreadPoolExecutor threadPool;

    static {
        threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,
                MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue,
                threadFactory);
    }


    /**
     * 从线程池中抽取线程,执行指定的Runnable对象
     * @param runnable
     */
    public static void execute(Runnable runnable){
        threadPool.execute(runnable);
    }
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12788次
    • 积分:696
    • 等级:
    • 排名:千里之外
    • 原创:59篇
    • 转载:3篇
    • 译文:0篇
    • 评论:0条
    文章分类