分段下载-实现

public static void downloadRangeFile(String pathAndName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String rangeInfo = request.getHeader("Range");
        if (StringUtils.isEmpty(rangeInfo)) {
            FileUtil.downloadLocalFile(pathAndName, request, response);
        } else {
            // 根据不同浏览器,解决中文乱码问题
            OutputStream outputStream = response.getOutputStream();
            File file = new File(pathAndName);
            try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {

                // FileChannel fileChannel = randomAccessFile.getChannel();
                String fileName = FileUtil.getZhFileName(request, file.getName());
                Long fileLength = file.length();
                Long contentLength = 0L;
                String rangStr = rangeInfo.substring(rangeInfo.indexOf("=") + 1);
                String[] rangeArray = rangStr.split(",");
                ArrayList<String> buildList = new ArrayList();

                for (String range : rangeArray) {
                    Long currentContentLength = 0L;
                    String notEmptyStr = StringUtils.trimAllWhitespace(range);
                    Long start = 0l;
                    Long end = 0l;
                    String[] temp = notEmptyStr.split("-");
                    if (notEmptyStr.startsWith("-")) {
                        end = fileLength - 1;
                        currentContentLength = Long.valueOf(temp[1]);
                        start = end - currentContentLength + 1;
                    } else if (notEmptyStr.endsWith("-")) {
                        start = Long.valueOf(temp[0]);
                        end = fileLength - 1;
                    } else {
                        start = Long.valueOf(temp[0]);
                        end = Long.valueOf(temp[1]);
                    }

                    start = start > fileLength - 1 ? (fileLength - 1) : start;
                    start = start < 0 ? 0 : start;
                    end = end > fileLength - 1 ? (fileLength - 1) : end;
                    end = end < 0 ? 0 : end;
                    end = end < start ? start : end;

                    buildList.add(start + "-" + end);
                    currentContentLength = end - start + 1;
                    currentContentLength = currentContentLength > fileLength ? fileLength : currentContentLength;
                    contentLength = contentLength + currentContentLength;
                }
                response.setHeader("Accept-Ranges", "bytes");
                // response.setHeader("E-tag", );暂时不填充该字段
                response.setHeader("Last-Modified", new Date(file.lastModified()).toString());
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                        String.format("attachment; filename=\"%s\"; filename*=utf-8''%s", fileName, fileName));
                response.setContentType("application/octet-stream");
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                response.setHeader("Content-Range", String.join(",", buildList) + "/" + fileLength);
                response.setContentLengthLong(contentLength);
                if (fileLength != 0) {
                    for (String str : buildList) {
                        Long currentContentLength = 0L;
                        String[] temp = str.split("-");
                        randomAccessFile.seek(Long.valueOf(temp[0]));
                        currentContentLength = Long.valueOf(temp[1]) - Long.valueOf(temp[0]) + 1;
                        Long index = 0L;
                        while (index < currentContentLength) {
                            byte[] buff;
                            if ((currentContentLength - index) >= BUFFER_LENGTH) {
                                buff = new byte[BUFFER_LENGTH];
                                index = index + BUFFER_LENGTH;
                            } else {
                                buff = new byte[(int) (currentContentLength - index)];
                                index = currentContentLength;
                            }
                            randomAccessFile.read(buff);
                            outputStream.write(buff);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("range download error", e);
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            } finally {
                outputStream.flush();
                outputStream.close();
            }
        }


    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值