上传文件的处理

分片上传
1.查询是否已经上传
2.分片发送
3.提交

注意,md5加密,是通过加密文件的前1024个字节,md5加密如果是通过字节数组加密,会有安全问题,所有改成加密流。
这个有一个问题,如果是txt文件,前1024个字节都是一样的情况下,后面的内容不管怎么变,文件都会被加一样的密
每次分片上传2M

import org.apache.http.HttpEntity;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class FileUploadUtil{

	private final int UPLOAD_PART_SIZE = 1024 * 1024 * 2;
	private final int SIZE_1024 = 1024;
	private byte[] bytes = new byte[SIZE_1024];
		
	public String uploadCloud(InputStream is, long fileSize, String fileName) throws Exception {
		
		String fileMd5 = md5Stream(is, fileSize);

		Boolean status = query(fileMd5, fileSize);
		if (!status) {
			saveData(is, fileMd5, fileName, fileSize);
		}
		return finish(fileMd5, fileName, fileSize);
	}  

	private String md5Stream(InputStream is, long fileSize) throws IOException {
		if (fileSize < SIZE_1024) {
			bytes = new byte[(int) fileSize];
		}
		int num = is.read(bytes);

		InputStream md5Is = new ByteArrayInputStream(bytes, 0, num);

		return DigestUtils.md5Hex(md5Is);
	}
	
	private Boolean query(String fileMd5){
		
	}
	
	private void saveData(InputStream stream,String fileMd5, String fileName, long fileSize){

        if (fileSize <= SIZE_1024) {
            InputStream streamPart = new ByteArrayInputStream(bytes);
            savePartData(fileMd5, 0L, streamPart, fileName, fileSize);
            return;
        }

        long loop = fileSize / UPLOAD_PART_SIZE;
        long last = fileSize % UPLOAD_PART_SIZE;
        if (last > 0) {
            loop += 1;
        }

        long chunk = 0;
        // 分片号,表示文件分片的索引,从0开始
        do {
            byte[] buf = getBufBytes(loop, last, chunk);

            byte[] merge = new byte[0];
            if (chunk == 0) {
                merge = new byte[buf.length + SIZE_1024];
            }

            int num = stream.read(buf);
            if (chunk == 0) {
                System.arraycopy(bytes, 0, merge, 0, SIZE_1024);
                System.arraycopy(buf, 0, merge, SIZE_1024, num);
            } else {
                merge = buf;
            }

            // 分片上传,每次上传不超过2M
            InputStream streamPart = new ByteArrayInputStream(merge);
            savePartData(headerParamsMap, fileMd5, chunk, streamPart, fileName, fileSize);
            chunk++;
        } while (chunk < loop);
    }

    private byte[] getBufBytes(long loop, long last, long chunk) {
        byte[] buf;
        if (last > 0 && chunk == loop - 1) {
            if (chunk == 0) {
                buf = new byte[(int) last - bytes.length];
            } else {
                buf = new byte[(int) last];
            }
        } else if (chunk == 0) {
            buf = new byte[UPLOAD_PART_SIZE - bytes.length];
        } else {
            buf = new byte[UPLOAD_PART_SIZE];
        }
        return buf;
    }
	
	private void savePartData(String fileMd5, Long chunk,InputStream streamPart, String fileName, long fileSize)IOException {

        String url = 'http://xxxxxx';
        HttpPost httpPost = new HttpPost(url);

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addBinaryBody(FILE, streamPart, ContentType.MULTIPART_FORM_DATA, String.valueOf(chunk));
        builder.addTextBody(FILE_MD5, fileMd5);
        builder.addTextBody(FILE_NAME, fileName);
        builder.addTextBody(CHUNK, String.valueOf(chunk));
        builder.addTextBody(MD5_DIRECT_TRANSFER_ENABLE, String.valueOf(true));
        builder.addTextBody(FILE_SIZE, String.valueOf(fileSize));
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);

        /* 如果分片上传失败重试5次 */
        Boolean send;
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        int count = 4;
        try {
            client = HttpClients.createDefault();

            do {
                response = client.execute(httpPost);
                String bo = responseParseStr(response, "sendPartData");
                send = new Boolean(bo);
                logger.info("sendPartData" + send);
            } while (!send && count-- > 0);

        } catch (Exception e) {
            logger.error("sendPartData:", e);
            throw new BusiException();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }
            } catch (IOException e) {
                logger.error("close exception:", e);
            }
        }
    }
	
	private String finish(String fileMd5, String fileName, long size) throws Exception {
        String url = "xxxxxxx";
        HttpPost httpPost = new HttpPost(url);
        String id;
		
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addTextBody(FILE_MD5, fileMd5);
        builder.addTextBody(FILE_NAME, fileName);
        builder.addTextBody(FILE_SIZE, String.valueOf(size));
        builder.addTextBody(MD5_DIRECT_TRANSFER_ENABLE, String.valueOf(true));
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);

        try (CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost)) {
            JSONObject bo = responseParseJson(response);
            id = bo.getString("key");
        } catch (Exception e) {
            logger.error("finishPartObject:", e);
            throw new BusiException();
        }

        return id;
    }
	
	
	//下载 是通过一个上传的id来下载
	@Override
    public String download(String id, String fileName) throws BusiException, IOException {

        if (StringUtils.isEmpty(id)) {
            throw new BusiException();
        }

        String url = "xxxxxxxxxx";
        HttpPost httpPost = new HttpPost(url);

        // 请求参数   ENCRYP_VALUE: 1->只读   7->可编辑
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> encryptProfile = new HashedMap(8);
        encryptProfile.put(KEY, id);
        encryptProfile.put(USE_ID, "zhangsan001");
        encryptProfile.put(ENCRYP_ENABLE, false);
        encryptProfile.put(ENCRYP_VALUE, 7);
        encryptProfile.put(FIXED_READ, 1);
        list.add(encryptProfile);

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addTextBody(KEY, id);
        builder.addTextBody(DOWNLOAD_NAME, fileName);
        builder.addTextBody(LIMIT_COUNT, "-1");
        builder.addTextBody(ENCRYPT_PROFILE, JSON.toJSONString(list));

        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);

        try (CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost)) {
            return 解析返回一个可以直接在浏览下载的url;
        } catch (Exception e) {
            logger.error("downloadToken:", e);
            throw new BusiException();
        }
    }
}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值