断点续传流式下载 适合大文件(以流的形式向页面输出数据) @param physicalPath 完整路径(路径+文件名称) @param fileName 文件名称 @param request 响应信息 @return
(String physicalPath, String fileName,String rangeHeader, HttpServletRequest request,HttpServletResponse response)
| 344 | * @return |
| 345 | */ |
| 346 | public static ResponseEntity<StreamingResponseBody> rangeDownloadResponse(String physicalPath, String fileName,String rangeHeader, HttpServletRequest request,HttpServletResponse response) { |
| 347 | |
| 348 | Path filePath = Paths.get(physicalPath); |
| 349 | |
| 350 | long fileLength = 0L; |
| 351 | try (FileChannel fileChannel = FileChannel.open(filePath)) { |
| 352 | fileLength = fileChannel.size(); |
| 353 | } catch (IOException e) { |
| 354 | if (logger.isErrorEnabled()) { |
| 355 | logger.error("读取文件长度错误"+physicalPath,e); |
| 356 | } |
| 357 | return ResponseEntity.badRequest().build(); |
| 358 | } |
| 359 | |
| 360 | |
| 361 | long rangeStart = 0L; |
| 362 | long rangeEnd = fileLength; |
| 363 | |
| 364 | |
| 365 | if (rangeHeader != null) { |
| 366 | //example: bytes=0-1023 表示从0取到1023,长度为1024 |
| 367 | String[] ranges = rangeHeader.substring("bytes=".length()).split("-"); |
| 368 | rangeStart = Long.parseLong(ranges[0]); |
| 369 | if (ranges.length > 1) { |
| 370 | rangeEnd = Long.parseLong(ranges[1]) + 1; |
| 371 | } |
| 372 | } |
| 373 | final long skip = rangeStart; |
| 374 | final long contentLength = rangeEnd - rangeStart; |
| 375 | |
| 376 | |
| 377 | StreamingResponseBody streamingResponseBody = new StreamingResponseBody() { |
| 378 | @Override |
| 379 | public void writeTo(OutputStream outputStream) throws IOException { |
| 380 | try( InputStream inputStream = Files.newInputStream(filePath); |
| 381 | BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); |
| 382 | ){ |
| 383 | |
| 384 | bufferedInputStream.skip(skip); |
| 385 | byte[] bytes = new byte[1024]; |
| 386 | long readSum = 0; |
| 387 | int readCount = 0; |
| 388 | while ((readCount = bufferedInputStream.read(bytes)) != -1) { |
| 389 | if (readSum + readCount > contentLength) { |
| 390 | outputStream.write(bytes, 0, (int) (contentLength - readSum)); |
| 391 | } else { |
| 392 | outputStream.write(bytes, 0, readCount); |
| 393 | } |
| 394 | readSum = readSum + readCount; |
| 395 | } |
| 396 | outputStream.flush(); |
| 397 | |
| 398 | } |
| 399 | |
| 400 | } |
| 401 | }; |
| 402 | |
| 403 | String header = request.getHeader("User-Agent").toUpperCase(); |