使用jQuery File Upload分片上传文件

时间:2024-04-03 18:00:35

1. 设置fileupload空间的最大分片大小

$('.fileupload').fileupload({
    ...
    maxChunkSize: 10000000, // 10 MB
    ...
});

这样会将文件切分成10MB的大小放在multipart/form-data请求中上传到服务器,并在请求头中增加Content-Range属性,标识总的文件大小和该分片在整个文件的起始、终止位置,如下图:

第一个分片使用jQuery File Upload分片上传文件
第二个分片使用jQuery File Upload分片上传文件
。。
最后一个分片使用jQuery File Upload分片上传文件

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();
 }