1. 设置fileupload空间的最大分片大小
$('.fileupload').fileupload({
...
maxChunkSize: 10000000, // 10 MB
...
});
这样会将文件切分成10MB的大小放在multipart/form-data请求中上传到服务器,并在请求头中增加Content-Range属性,标识总的文件大小和该分片在整个文件的起始、终止位置,如下图:
第一个分片
第二个分片
。。
最后一个分片
2. 服务端接收分片然后合并
1.处理请求头,计算分片属于文件的第几块numBlock。
String content_range = content_range_str.split(" ")[1];
String bytesFromTo = content_range.split("/")[0];
int byteTotal = Integer.parseInt(content_range.split("/")[1]);
int byteFrom = Integer.parseInt(bytesFromTo.split("-")[0]);
int byteTo = Integer.parseInt(bytesFromTo.split("-")[1]);
int numBlock = 0;
boolean last = false;
if (byteTo == byteTotal - 1) {
last = true;
} else {
int blockSize = byteTo - byteFrom;
numBlock = byteFrom / blockSize;
}
2.以{文件名numBlock}的名字保存在一个新建的临时文件夹中,该临时文件夹以{用户id文件名}命名。
File file = fileMap.get(key);
key = key.substring(key.lastIndexOf(File.separator) + 1);
key = key.substring(key.lastIndexOf("\\") + 1);
File userFileDir = new File(PathUtil.getTempPath() + userDirPath + key + File.separator);
if (!userFileDir.exists()) {
Files.createDirectories(userFileDir.toPath());
}
Path fileUri = Paths.get(userFileDir.getPath(), key + numBlock);
try {
Files.move(file.toPath(), fileUri, StandardCopyOption.REPLACE_EXISTING);
json.put("state", "1");
json.put("msg", "文件块" + numBlock + "保存成功");
} catch (IOException e) {
e.printStackTrace();
json.put("state", "0");
json.put("msg", "文件块" + numBlock + "保存失败");
json.put("error", e.toString());
}
jsonArray.add(json);
3.合并临时文件夹{用户id文件名}中的文件
File userFileDir = new File(PathUtil.getTempPath() + userDirPath + key);
File completedFile = new File(uploadPath + userDirPath + key);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(completedFile);
FileChannel fileChannel = outputStream.getChannel();
fileChannel.force(true);
File inputFile;
int totalBlock = userFileDir.listFiles().length;
for (int i = 0; i < totalBlock; i++) {
inputFile = new File(userFileDir.getPath() + File.separator + key + i);
mergeFile(fileChannel, inputFile);
}
File lastFile = fileMap.get(key);
mergeFile(fileChannel, lastFile);
fileChannel.close();
outputStream.close();
json = upload2NetDisk(completedFile, userInfo);
json.put("state", "1");
json.put("msg", "文件" + key + "上传成功");
} catch (Exception e) {
e.printStackTrace();
json.put("state", "0");
json.put("msg", "文件" + key + "上传失败");
json.put("error", e.toString());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
jsonArray.add(json);
合并方法
private void mergeFile(FileChannel out, File inputFile) throws IOException {
FileInputStream inputStream = new FileInputStream(inputFile);
FileChannel in = inputStream.getChannel();
in.transferTo(0, in.size(), out);
in.close();
inputStream.close();
inputFile.delete();
}