admin管理员组

文章数量:1642444

Spring Boot文件下载断点续传

  • 正文
  • MimeType映射关系

正文

  @RequestMapping(value = {
    "/downloading" }, method = {
    RequestMethod.POST, RequestMethod.GET })
  public void insertNode(
      HttpServletRequest request, 
      HttpServletResponse response,
      // 获取Header里面的Range内容, 可选项, 可为空
      @RequestHeader(name = "Range", required = false) String range) {
   

    // 测试用文件
    File file = new File("F:/F.zip");

    // 设置Content-Type, 此处可以参考void org.apache.catalina.startup.Tomcat.addDefaultMimeTypeMappings(Context context)
    // 采用的是扩展名判断Content-Type, 内容可以参考org.apache.catalina.startup.MimeTypeMappings.properties
    String mimeType = request.getServletContext().getMimeType(file.getName());
    response.setContentType(null != mimeType ? mimeType : "application/octet-stream; charset=UTF-8");
    // 自定义文件名
    response.setHeader("Content-Disposition", String.format("attachment; filename=%s", file.getName()));
    response.setHeader("Accept-Ranges", "bytes");

    try (
        // 获取Response输出流
        ServletOutputStream out = response.getOutputStream();
        // 测试用文件出入流
        InputStream fis = new FileInputStream(file);) {
   
      // fis.available()可以获取有限数据流总大小, 但available()返回的是int类型, 适用于小于2 G的文件
      // file.length()可以获取文件大小, 返回的是long类型, 适用于小于8.4215048E7 P的文件
      long length = file.length(); // 获取数据流总大小
      long from = 0, to = length - 1; // 定义有效数据流起始, 截止位置
      if (null == range) {
   
        response.setHeader("Content-Length", Long.toString(length));
      } else {
   
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        String[] ranges = range.replace("bytes=", "").split("-");
        if (ranges.length > 0) from = Long.parseLong(ranges[0]);
        if (ranges.length > 1) to = Long.parseLong(ranges[1]);
        // 设置本批次数据大小
        response.setHeader("Content-Length", Long.toString(to - from + 1L));
        // 设置本批次数据范围及数据总大小
        response.setHeader("Accept-Ranges", String.format("bytes %d-%d/%d", from, to, length));
      }
      fis.skip(from); // 跳过不需要的数据内容
      long limit = to - from + 1; // 限制数据流大小, 最大等于文件大小
      // 缓冲大小
      int bufferSize = (int) (limit > 2048 ? 2048 : limit);
      // 创建缓冲数组
      byte[] buffer = new byte[bufferSize];
      int num = 0;
      while (0 < limit && (num = fis.read(buffer)) != -1) {
   
        out.write(buffer, 0, num);
        limit -= num;
        if (limit < bufferSize) {
   
          buffer = new byte[(int) limit];
        }
      }
      response.flushBuffer();
    } catch (IOException e) {
   
      // TODO :: [远程主机强迫关闭了一个现有的连接。]... 等异常处理
    }

  }

MimeType映射关系

# 内容摘自: org.apache.catalina.startup.MimeTypeMappings.properties

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

123=application/vnd.lotus-1-2-3
3dml=text/vnd.in3d.3dml
3ds=image/x-3ds
3g2=video/3gpp2
3gp=video/3gpp
7z=application/x-7z-compressed
aab=application/x-authorware-bin
aac=audio/x-aac
aam=application/x-authorware-map
aas=

本文标签: 断点续传文件Springboot