这里提供两种文件分块的方式:
1.手动进行文件的切分从而讲形成的块文件进行上传
2.利用contentBody 重写write的方法切割文件实现上传
对文件的切割用的是
RandomAccessFile 这个对象去读文件,
RandomAccessFile raf = new RandomAccessFile(targetFile, "r");
raf对象的seek()方法可跳跃前多少个字节进行读取文件,实现大文件的分块。
package com.wondersgroup.wbgl.web.Test2;
import com.wondersgroup.core.exceptions.ExcelException;
import com.wondersgroup.core.util.DateUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
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.entity.mime.content.AbstractContentBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
public class Test {
public static class BlockStreamBody extends AbstractContentBody {
public static long CLOUD_API_LOGON_SIZE = 10 * 1024 * 1024;
//给MultipartEntity看的2个参数
private long blockSize = 0;//本次分块上传的大小
private String fileName = null;//上传文件名
//writeTo需要的3个参数
private int blockNumber = 0, blockIndex = 0;//blockNumber分块数;blockIndex当前第几块
private File targetFile = null;//要上传的文件
private BlockStreamBody(String mimeType) {
super(mimeType);
// TODO Auto-generated constructor stub
}
/**
* 自定义的ContentBody构造子
*
* @param blockNumber 分块数
* @param blockIndex 当前第几块
* @param targetFile 要上传的文件
*/
public BlockStreamBody(int blockNumber, int blockIndex, File targetFile) {
this("application/octet-stream");
this.blockNumber = blockNumber;//blockNumber初始化
this.blockIndex = blockIndex;//blockIndex初始化
this.targetFile = targetFile;//targetFile初始化
this.fileName = targetFile.getName();//fileName初始化
//blockSize初始化
if (blockIndex < blockNumber) {//不是最后一块,那就是固定大小了
this.blockSize = CLOUD_API_LOGON_SIZE;
} else {//最后一块
this.blockSize = targetFile.length() - CLOUD_API_LOGON_SIZE * (blockNumber - 1);
}
}
@Override
public void writeTo(OutputStream out) throws IOException {
RandomAccessFile raf = new RandomAccessFile(targetFile, "r");//负责读取数据
byte b[] = new byte[1024];//暂存容器
if (blockIndex == 1) {//第一块
int n = 0;
long readLength = 0;//记录已读字节数
while (readLength <= blockSize - 1024) {//大部分字节在这里读取
n = raf.read(b, 0, 1024);
readLength += 1024;
out.write(b, 0, n);
}
if (readLength <= blockSize) {//余下的不足 1024 个字节在这里读取
n = raf.read(b, 0, (int) (blockSize - readLength));
out.write(b, 0, n);
}
} else if (blockIndex < blockNumber) {//既不是第一块,也不是最后一块
raf.seek(CLOUD_API_LOGON_SIZE * (blockIndex - 1));//跳过前[块数*固定大小 ]个字节
int n = 0;
long readLength = 0;//记录已读字节数
while (readLength <= blockSize - 1024) {//大部分字节在这里读取
n = raf.read(b, 0, 1024);
readLength += 1024;
out.write(b, 0, n);
}
if (readLength <= blockSize) {//余下的不足 1024 个字节在这里读取
n = raf.read(b, 0, (int) (blockSize - readLength));
out.write(b, 0, n);
}
} else {//最后一块
raf.seek(CLOUD_API_LOGON_SIZE * (blockIndex - 1));//跳过前[块数*固定大小 ]个字节
int n = 0;
while ((n = raf.read(b, 0, 1024)) != -1) {
out.write(b, 0, n);
}
}
raf.close();
//TODO 最后不要忘掉关闭out/raf
}
@Override
public String getCharset() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getTransferEncoding() {
// TODO Auto-generated method stub
return "binary";
}
@Override
public String getFilename() {
// TODO Auto-generated method stub
return fileName;
}
@Override
public long getContentLength() {
// TODO Auto-generated method stub
return blockSize;
}
}
private static BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(20);
private static ExecutorService executorService = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, blockingQueue, new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
while (!blockingQueue.offer(r)) {
}
}
});
public static long CLOUD_API_LOGON_SIZE = 10* 1024*1024;
public static int timeOut = 60*60*1000;
public static final String checkURL = "http://localhost:8080/claim/private/checked/checkChunk.do";
public static final String mergeURL = "";
public static final String uploadURL = "";
public static void main(String[] args) throws Exception {
String filePath = "E:\\workspace\\wbglProject\\dispatcher\\target\\dispatcher.war";
System.out.println("开始上传"+ DateUtil.dateToString3(new Date()));
uploadToDrive(filePath);
System.out.println("上传结束"+ DateUtil.dateToString3(new Date()));
}
/**
* 上传文件处理及参数封装
*
* @param filePath
* @throws Exception
*/
public static void uploadToDrive(String filePath)throws Exception {
File targetFile = new File(filePath);
HashMap<String, Object> params = new HashMap<String, Object>();
File file = new File(filePath);
params.put("fileName",file.getName());
params.put("fileLength",file.length());
String md5 = DigestUtils.md5Hex(new FileInputStream(file));
params.put("md5",md5);
BufferedReader in = null;
long someExtra = 0;
long targetFileSize = targetFile.length();
int mBlockNumber = 0;
if (targetFileSize < CLOUD_API_LOGON_SIZE) {
mBlockNumber = 1;
someExtra = targetFileSize;
} else {
mBlockNumber = (int) (targetFileSize / CLOUD_API_LOGON_SIZE);
someExtra = targetFileSize
% CLOUD_API_LOGON_SIZE;
if (someExtra > 0) {
mBlockNumber++;
}
}
params.put("chunkNum", Integer.toString(mBlockNumber));
List<Callable<String>> callableList = new ArrayList<Callable<String>>();
// 定义BufferedReader输入流来读取URL的响应,设置编码方式
for (int i = 1; i <= mBlockNumber; i++) {
int chunkIndex = i;
params.put("chunkIndex", i);
long chunkSize = CLOUD_API_LOGON_SIZE;
params.put("chunkSize", CLOUD_API_LOGON_SIZE);
if (i == mBlockNumber) {
chunkSize = someExtra == 0 ? CLOUD_API_LOGON_SIZE : someExtra;
params.put("chunkSize", (someExtra == 0 ? CLOUD_API_LOGON_SIZE : someExtra) + "");
}
//
UploadThread thread = new UploadThread(chunkIndex , chunkSize , targetFile , params,makeHeads());
callableList.add(thread);
}
List<Future<String>> futures = executorService.invokeAll(callableList);
restPost(mergeURL,params,makeHeads(),targetFile);
}
/**
* 发送请求
*
* @param url 请求路径
* @param params 请求参数
* @param heads 请求头
* @param targetFile 上传的文件
* @return String
*/
public static String restPost(String url, Map<String, Object> params, Map<String, String> heads,File targetFile) {
HttpClient httpClient = null;
HttpPost httpPost = new HttpPost(url);
String content="";
try {
MultipartEntityBuilder mpEntity = MultipartEntityBuilder.create();
for (String head : heads.keySet()) {
httpPost.setHeader(head, heads.get(head));
}
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
if (null != params && params.size() > 0) {
for (String param : params.keySet()) {
mpEntity.addPart(param, new StringBody(params.get(param).toString(), ContentType.MULTIPART_FORM_DATA));}
}
mpEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if (targetFile != null && targetFile.exists()) {
ContentBody contentBody = new BlockStreamBody(Integer.parseInt(params.get("chunkNum").toString()), Integer.parseInt(params.get("chunkIndex").toString()), targetFile);
mpEntity.addPart("file", contentBody);
}
httpPost.setEntity(mpEntity.build());
httpClient = HttpClientBuilder.create().build();
RequestConfig.Builder build = RequestConfig.custom();
build.setConnectTimeout(timeOut);
build.setSocketTimeout(timeOut);
HttpResponse execute = httpClient.execute(httpPost);
content = IOUtils.toString(execute.getEntity().getContent(), "utf-8");
System.out.println(content);
}catch (Exception e){
e.printStackTrace();
throw new ExcelException(e.getMessage());
}
int i=0;
i++;
System.out.println(i+"=============响应结果==================\n"+content);
System.out.println("=============end==================\n");
return content.trim();
}
public static Map<String, String> makeHeads(){
Map<String, String> heads = new HashMap<String, String>();
heads.put("serviceNo","YB");
heads.put("serviceKey","6a69b7af4eba48859d7e71ed652e958e");
heads.put("fileType","4");
return heads;
}
public static class UploadThread implements Callable<String>{
private final int chunkIndex;
private final long chunkSize;
private final File targetFile;
private Map<String , String> heads = new HashMap<String, String>();
private Map<String , Object> params = new HashMap<String,Object>();
public UploadThread(int chunkIndex, long chunkSize, File targetFile,Map<String,Object> params,Map<String , String> heads) {
this.chunkIndex = chunkIndex;
this.chunkSize = chunkSize;
this.targetFile = targetFile;
this.params.putAll(params);
this.heads.putAll(heads);
}
@Override
public String call() throws Exception {
String s = restPost(checkURL, params, heads, null);
Map<String,Object> retmap = (Map)com.alibaba.fastjson.JSON.parse(s);
Map body =(Map) retmap.get("body");
Object isExist = body.get("isExist");
if(isExist.toString().equals("false")){
String s2 = restPost(uploadURL,params ,heads, targetFile);
}
return "";
}
}
}
2.手动切分文件实现上传
package com.wondersgroup.wbgl.web.Test;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.wondersgroup.core.util.LogUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.*;
public class TestChunkUpload {
private static final Logger logger = LogUtil.getLogger(TestChunkUpload.class);
public static final String check_url = "http://localhost:8080/wbgl/service/claim/private/checked/checkChunk.do";
public static final String upload_url = "http://localhost:8080/wbgl/service/claim/private/checked/merge.do";
public static final String merge_url = "http://localhost:8080/wbgl/service/claim/private/checked/upload.do";
/* private static String check_url = "http://182.150.61.17:31001/wbglWeb/service/claim/private/checked/checkChunk.do";
private static String upload_url = "http://182.150.61.17:31001/wbglWeb/service/claim/private/checked/upload.do";
private static String merge_url = "http://182.150.61.17:31001/wbglWeb/service/claim/private/checked/merge.do";*/
private static String serviceNo = "PK";
private static String serviceKey = "b42bc810c84d45a08251a3ceeb84a7fe";
private static String tempPath = "E:\\files";
private ExecutorService executorService = Executors.newFixedThreadPool(5);
public static void main(String[] args) {
/* 验证拆分
File file = new File("/Users/liqingdong/Temp/plsqldev1106x64.exe");
Map<String, Object> chunkInfo = new TestChunkUpload().getChunkInfo(file, 7);
System.out.println(chunkInfo.toString());
*/
/* 验证合并
try {
File merge = new TestChunkUpload().merge("/Users/liqingdong/Temp/d9867da93be8fa1d64abb344adb30586");
FileInputStream fis = new FileInputStream(merge);
String md5Hex = DigestUtils.md5Hex(fis);
fis.close();
System.out.println(md5Hex);
} catch (IOException e) {
e.printStackTrace();
}
*/
File file = new File("D:\\BaiduNetdiskDownload\\12345.mp4");
TestChunkUpload testChunkUpload = new TestChunkUpload();
try {
testChunkUpload.uploadByThread("4", file);
} catch (InterruptedException e) {
logger.error(e.getMessage());
}
}
/**
* 文件上传
*
* @param fileType 上传文件类型
* @param file 上传文件
* @return
*/
@SuppressWarnings("unchecked")
public boolean upload(String fileType, File file) {
logger.info("文件:{} 开始上传...", file.getName());
long start = System.currentTimeMillis();
Map<String, Object> chunkInfo = getChunkInfo(file, 10);
List<Map<String, Object>> chunkList = (List<Map<String, Object>>) chunkInfo.get("chunkList");
int successCount = 0;
for (Map<String, Object> chunkFileInfo : chunkList) {
boolean exist = checkChunk(fileType, chunkInfo.get("md5").toString(), (Integer) chunkFileInfo.get("chunkIndex"), (Integer) chunkInfo.get("chunkNum"), (Long) chunkFileInfo.get("chunkSize"));
if (exist) continue;
boolean success = doUpload(fileType, (File) chunkFileInfo.get("chunkFile"), file.getName(), (Long) chunkInfo.get("fileLength"), chunkInfo.get("md5").toString(), (Integer) chunkFileInfo.get("chunkIndex"), (Integer) chunkInfo.get("chunkNum"), (Long) chunkFileInfo.get("chunkSize"));
if (success) successCount++;
}
boolean result = successCount == Integer.valueOf(chunkInfo.get("chunkNum").toString()) && merge(fileType, file.getName(), (Long) chunkInfo.get("fileLength"), chunkInfo.get("md5").toString(), (Integer) chunkInfo.get("chunkNum"));
logger.info("文件上传结束。本次上传总耗时:" + (System.currentTimeMillis() - start) / 1000 + "秒");
// 删除本地临时分块文件
File tempDir = new File(tempPath + File.separator + chunkInfo.get("md5").toString());
try {
FileUtils.deleteDirectory(tempDir);
} catch (IOException e) {
logger.error("删除临时文件失败,{}", e.getMessage());
}
return result;
}
/**
* 多线程文件上传
*
* @param fileType
* @param file
* @return
*/
@SuppressWarnings("unchecked")
public boolean uploadByThread(String fileType, File file) throws InterruptedException {
logger.info("文件:{} 开始上传...", file.getName());
long start = System.currentTimeMillis();
Map<String, Object> chunkInfo = getChunkInfo(file, 10);
List<Map<String, Object>> chunkList = (List<Map<String, Object>>) chunkInfo.get("chunkList");
List<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
for (Map<String, Object> chunkFileInfo : chunkList) {
Callable<Boolean> task = task(chunkInfo, chunkFileInfo, fileType, file);
tasks.add(task);
}
executorService.invokeAll(tasks);
boolean result = merge(fileType, file.getName(), (Long) chunkInfo.get("fileLength"), chunkInfo.get("md5").toString(), (Integer) chunkInfo.get("chunkNum"));
logger.info("文件上传结束。本次上传总耗时:" + (System.currentTimeMillis() - start) / 1000 + "秒");
return result;
}
private Callable<Boolean> task(final Map<String, Object> chunkInfo, final Map<String, Object> chunkFileInfo, final String fileType, final File file) {
return new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
boolean result = false;
System.out.println(Thread.currentThread().getName() + "开始执行...");
boolean exist = checkChunk(fileType, chunkInfo.get("md5").toString(), (Integer) chunkFileInfo.get("chunkIndex"), (Integer) chunkInfo.get("chunkNum"), (Long) chunkFileInfo.get("chunkSize"));
if (!exist) {
result = doUpload(fileType, (File) chunkFileInfo.get("chunkFile"), file.getName(), (Long) chunkInfo.get("fileLength"), chunkInfo.get("md5").toString(), (Integer) chunkFileInfo.get("chunkIndex"), (Integer) chunkInfo.get("chunkNum"), (Long) chunkFileInfo.get("chunkSize"));
}
System.out.println(Thread.currentThread().getName() + "执行结束.");
return exist || result;
}
};
}
/**
* 获取文件分块信息
*
* @param file 文件
* @param defaultSize 单块文件大小(单位:M)
* @return
*/
private Map<String, Object> getChunkInfo(File file, int defaultSize) {
Map<String, Object> result = new HashMap<String, Object>();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
String md5 = DigestUtils.md5Hex(fis);
result.put("md5", md5);
long fileLength = file.length();
result.put("fileLength", fileLength);
int defaultByteSize = defaultSize * 1024 * 1024;
int chunkNum = (int) Math.ceil(fileLength / (double) defaultByteSize);
result.put("chunkNum", chunkNum);
File chunkFile;
FileOutputStream fos;
File parentDirectory = new File(tempPath + File.separator + md5);
// 删除原有MD5目录,重新生成
if (parentDirectory.exists()) FileUtils.deleteDirectory(parentDirectory);
parentDirectory.mkdirs();
HashMap<String, Object> chunkFileInfo;// 单块文件信息
List<Map<String, Object>> chunkFiles = new ArrayList<Map<String, Object>>();// 文件块信息集合
byte[] bytes = new byte[defaultByteSize];
RandomAccessFile raf = new RandomAccessFile(file, "r");
for (int chunkIndex = 1; chunkIndex <= chunkNum; chunkIndex++) {
chunkFile = new File(parentDirectory, chunkIndex + ".temp");
chunkFile.createNewFile();
fos = new FileOutputStream(chunkFile);
int offset = (chunkIndex - 1) * defaultByteSize;// 文件读取偏移量
if (chunkIndex == chunkNum) {
bytes = new byte[((Long) (fileLength - offset)).intValue()];
}
raf.seek(offset);
raf.read(bytes);
fos.write(bytes);
fos.flush();
fos.close();
chunkFileInfo = new HashMap<String, Object>();
chunkFileInfo.put("chunkFile", chunkFile);
chunkFileInfo.put("chunkIndex", chunkIndex);
chunkFileInfo.put("chunkSize", chunkFile.length());
chunkFiles.add(chunkFileInfo);
}
raf.close();
result.put("chunkList", chunkFiles);
} catch (IOException e) {
logger.error(e.getMessage());
} finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return result;
}
/**
* 校验文件块
*
* @param fileType
* @param md5
* @param chunkIndex
* @param chunkNum
* @param chunkSize
* @return
*/
@SuppressWarnings("unchecked")
private boolean checkChunk(String fileType, String md5, int chunkIndex, int chunkNum, long chunkSize) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(check_url);
httpPost.addHeader("serviceNo", serviceNo);
httpPost.addHeader("serviceKey", serviceKey);
httpPost.addHeader("fileType", fileType);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("md5", new StringBody(md5, ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkIndex", new StringBody(String.valueOf(chunkIndex), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkNum", new StringBody(String.valueOf(chunkNum), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkSize", new StringBody(String.valueOf(chunkSize), ContentType.create("text/plain", Consts.UTF_8)))
.build();
httpPost.setEntity(reqEntity);
// 发起请求 并返回请求的响应
response = httpClient.execute(httpPost);
// 获取响应对象
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String result = EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
EntityUtils.consume(resEntity);// 销毁
logger.info("文件块[" + chunkIndex + "],校验响应结果:" + result);
Map<String, Object> map = new ObjectMapper().readValue(result, HashMap.class);
if (Boolean.valueOf(map.get("success").toString())) {
Map<String, Object> body = (Map<String, Object>) map.get("body");
return Boolean.valueOf(body.get("isExist").toString());
}
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
try {
if (response != null) response.close();
if (httpClient != null) httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return false;
}
/**
* 分块上传
*
* @param fileType 文件类型
* @param file 当前文件块
* @param md5 文件MD5
* @param chunkIndex 当前文件分块下标
* @param chunkNum 文件总块数
* @param chunkSize 文件大小
*/
@SuppressWarnings("unchecked")
private boolean doUpload(String fileType, File file, String fileName, long fileLength, String md5, int chunkIndex, int chunkNum, long chunkSize) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(upload_url);
httpPost.addHeader("serviceNo", serviceNo);
httpPost.addHeader("serviceKey", serviceKey);
httpPost.addHeader("fileType", fileType);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("file", new FileBody(file))
.addPart("md5", new StringBody(md5, ContentType.create("text/plain", Consts.UTF_8)))
.addPart("fileName", new StringBody(fileName, ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkIndex", new StringBody(String.valueOf(chunkIndex), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkNum", new StringBody(String.valueOf(chunkNum), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkSize", new StringBody(String.valueOf(chunkSize), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("fileLength", new StringBody(String.valueOf(fileLength), ContentType.create("text/plain", Consts.UTF_8)))
.build();
httpPost.setEntity(reqEntity);
// 发起请求 并返回请求的响应
response = httpClient.execute(httpPost);
// 获取响应对象
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String result = EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
EntityUtils.consume(resEntity);
logger.info("文件块[" + chunkIndex + "],上传响应结果:" + result);
Map<String, Object> map = new ObjectMapper().readValue(result, Map.class);
return Boolean.valueOf(map.get("success").toString());
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
try {
if (response != null) response.close();
if (httpClient != null) httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return false;
}
/**
* 本地测试文件合并
*
* @param path
* @return
* @throws IOException
*/
public File merge(String path) throws IOException {
File file = new File(path);
File[] files = file.listFiles();
TreeSet<File> treeSet = new TreeSet<File>(new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return o1.getName().substring(0, o1.getName().indexOf(".")).compareTo(o2.getName().substring(0, o2.getName().indexOf(".")));
}
});
treeSet.addAll(Arrays.asList(files));
File merge = new File(file.getParentFile(), "new.exe");
if (merge.exists()) FileUtils.deleteQuietly(merge);
merge.createNewFile();
FileOutputStream fos = new FileOutputStream(merge);
FileInputStream fis;
for (File f : treeSet) {
fis = new FileInputStream(f);
IOUtils.copy(fis, fos);
fis.close();
}
fos.flush();
fos.close();
return merge;
}
/**
* 分块文件合并
*
* @param fileType
* @param fileName
* @param fileLength
* @param md5
* @param chunkNum
* @return
*/
@SuppressWarnings("unchecked")
private boolean merge(String fileType, String fileName, long fileLength, String md5, int chunkNum) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(merge_url);
httpPost.addHeader("serviceNo", serviceNo);
httpPost.addHeader("serviceKey", serviceKey);
httpPost.addHeader("fileType", fileType);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("md5", new StringBody(md5, ContentType.create("text/plain", Consts.UTF_8)))
.addPart("fileName", new StringBody(fileName, ContentType.create("text/plain", Consts.UTF_8)))
.addPart("chunkNum", new StringBody(String.valueOf(chunkNum), ContentType.create("text/plain", Consts.UTF_8)))
.addPart("fileLength", new StringBody(String.valueOf(fileLength), ContentType.create("text/plain", Consts.UTF_8)))
.build();
httpPost.setEntity(reqEntity);
// 发起请求 并返回请求的响应
response = httpClient.execute(httpPost);
// 获取响应对象
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String result = EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
EntityUtils.consume(resEntity);
logger.info("文件:{}合并响应结果:" + result, fileName);
Map<String, Object> map = new ObjectMapper().readValue(result, Map.class);
return Boolean.valueOf(map.get("success").toString());
}
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
try {
if (response != null) response.close();
if (httpClient != null) httpClient.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return false;
}
}