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();
}
}
}
分段下载-实现
最新推荐文章于 2024-10-12 22:35:37 发布