|
|
@@ -16,6 +16,8 @@ import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import org.apache.commons.io.IOUtils;
|
|
|
@@ -295,6 +297,84 @@ public class FileServiceImpl implements FileService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void rangeDownload(File file, String fileName, HttpServletRequest request, HttpServletResponse response)
|
|
|
+ throws IOException {
|
|
|
+ if (file == null) {
|
|
|
+ throw new IllegalArgumentException("参数不能为空:file");
|
|
|
+ }
|
|
|
+ if (!file.exists() || !file.isFile()) {
|
|
|
+ throw new IOException("文件不存在或并非文件");
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(fileName)) {
|
|
|
+ fileName = file.getName();
|
|
|
+ }
|
|
|
+ FileInputStream fis = new FileInputStream(file);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 告知客户端支持 Accept-Ranges
|
|
|
+ response.reset();
|
|
|
+ response.setHeader("Accept-Ranges", "bytes");
|
|
|
+
|
|
|
+ long total = file.length();
|
|
|
+ long start = 0;
|
|
|
+ long end = total - 1;
|
|
|
+ String rangeHeader = request.getHeader("Range");
|
|
|
+ if (!StringUtils.isEmpty(rangeHeader)) {
|
|
|
+ // 告知客户端支持块下载
|
|
|
+ // HTTP/1.1 206 Partial Content
|
|
|
+ response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
|
|
+ rangeHeader = rangeHeader.replace("bytes=", "");
|
|
|
+ // bytes=577215295-
|
|
|
+ if (rangeHeader.endsWith("-")) {
|
|
|
+ // 获取文件块的开始字节位置
|
|
|
+ start = Long.parseLong(rangeHeader.replace("bytes=", "").replace("-", ""));
|
|
|
+ }
|
|
|
+ // bytes=961849437-1153518704
|
|
|
+ else {
|
|
|
+ int index = rangeHeader.indexOf("-");
|
|
|
+ if (index < 0) {
|
|
|
+ throw new IllegalArgumentException("Ranger 格式错误:" + request.getHeader("Range"));
|
|
|
+ }
|
|
|
+ // 获取文件块的开始和结束字节位置
|
|
|
+ start = Long.parseLong(rangeHeader.substring(0, index));
|
|
|
+ end = Long.parseLong(rangeHeader.substring(index + 1));
|
|
|
+ }
|
|
|
+ if (start < 0 || start >= total || end < 0 || end >= total || start > end) {
|
|
|
+ throw new IllegalArgumentException("Ranger 格式错误:" + request.getHeader("Range"));
|
|
|
+ }
|
|
|
+ response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + total);
|
|
|
+ fis.skip(start);
|
|
|
+ }
|
|
|
+
|
|
|
+ long contentLength = end - start + 1;
|
|
|
+ response.setHeader("Content-Length", contentLength + "");
|
|
|
+ // response.setContentType("application/octet-stream");
|
|
|
+ response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
|
|
+
|
|
|
+ ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ byte[] data = new byte[1024];
|
|
|
+ int i;
|
|
|
+ int count = 0;
|
|
|
+ try {
|
|
|
+ while (count <= contentLength - 1024 && (i = fis.read(data)) != -1) {
|
|
|
+ outputStream.write(data, 0, i);
|
|
|
+ count += i;
|
|
|
+ }
|
|
|
+ if (count < contentLength) {
|
|
|
+ i = fis.read(data, 0, (int) (contentLength - count));
|
|
|
+ outputStream.write(data, 0, i);
|
|
|
+ }
|
|
|
+ outputStream.flush();
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.error(e.getMessage());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ fis.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public String delete(String filePath, Boolean isAbsolutePath) throws IOException {
|
|
|
// 路径不能为空,不能只包含'/'(根路径),不能含有'..'(不允许通过该方式删除上一级)
|