多线程上传文件

package com.jd.m.pthcms.common.util;

import com.jd.fastjson.JSONObject;
import com.jd.image.common.ImageUpload;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by huihui on 2017/5/16.
 */
public class FileUnzipUtil {

    private static final Logger log = Logger.getLogger(FileUnzipUtil.class);
    private static final int THREAD_SIZE = 7;

    public static Map unzip(File zipFile, String key) throws Exception {

        //解压,不支持包含文件夹
        ZipEntry entry = null;
        BufferedInputStream bis = null;
        ZipFile zip = null;
        ExecutorService executorService = null;
        ConcurrentHashMap resultMap = new ConcurrentHashMap();

        try {
            zip = new ZipFile(zipFile);
            Enumeration entries = (Enumeration) zip.getEntries();
            executorService = Executors.newFixedThreadPool(THREAD_SIZE);
            CompletionService ecs = new ExecutorCompletionService(executorService);
            int imageCount = 0;

            while (entries.hasMoreElements()) {
                entry = entries.nextElement();
                bis = new BufferedInputStream(zip.getInputStream(entry));
                ecs.submit(new UploadImage(resultMap, entry.getName(), IOUtils.toByteArray(bis), key));
                bis.close();
                imageCount++;
            }
            zip.close();

            //有一个失败,则返回null
            for (int i = 0; i < imageCount; i++) {
	   //只有通过execute提交的任务才能将它抛出的异常交给未捕获的异常处理器,而通过submit提交的任务,无论是抛出的未检查的异常,还是已检查的异常,
	   //都将被认为是任务返回状态的一部分。如果一个由submit提交的任务由于抛出异常而结束,那么这个异常将被Future.get封装在ExecutionException中重新抛出
                if (!ecs.take().get()) {
                    return null;
                }
            }
        } catch (Exception e) {
            log.error("上传图片出错!", e);
            return null;
        } finally {
            executorService.shutdown();
            if (bis != null) {
                bis.close();
            }
            if (zip != null) {
                zip.close();
            }
        }
        return resultMap;
    }

    static class UploadImage implements Callable {

        private ConcurrentHashMap resultMap;
        private String imgName;
        private byte[] imgBytes;
        private String key;

        public UploadImage(ConcurrentHashMap resultMap, String imgName, byte[] imgBytes, String key) {
            this.resultMap = resultMap;
            this.imgName = imgName;
            this.imgBytes = imgBytes;
            this.key = key;
        }

        @Override
        public Boolean call() {
            try {
                String msg = ImageUpload.uploadFile(imgBytes, key);
                if (StringUtils.isBlank(msg) || !msg.startsWith("[")) {
                    return false;
                }
                List msgList = JSONObject.parseArray(msg, Map.class);
                if (msgList.size() == 0 || !"1".equals(msgList.get(0).get("id") + "")) {
                    return false;
                }
                resultMap.put(imgName, msgList.get(0).get("msg") + "");
            } catch (Exception e) {
                log.error("上传图片出错!", e);
                return false;
            }
            return true;
        }
    }
}


你可能感兴趣的:(多线程)