s3断点下载
-
两个概念
http request中的请求头有一个header为 range
该字段表明请求的下载流从什么地方开始下载
例如
- RANGE: bytes=2000070-
表明从2000070开始一直下载到最后
-
RANGE: bytes=2000070-2000080
表明从2000070开始一直下载到2000080
如果在请求时使用了range字段,那么在返回的response中会有多出一个header即
Content-Range=bytes 100000-19999/20000
表明你下载的返回是100000-19999,一共有20000字节,这个字段非常重要,服务器根据请求头的Content-Range来决定从文件流的哪个位置上开始读,并且需要返回状态码为206,表示部分请求成功,这些都是附加信息,告诉服务器需要怎样返回流
response header属性详解
-
代码 (说明一下:此处的s3自动帮我们完成了响应的流的内容,因此我们不需要在response中进行header的设置)
@ApiOperation("下载文件") @RequestMapping(value = "/downloadFile",method = RequestMethod.GET) public RestResult<?> downFile(@RequestParam(value="fileName")String fileName, String userId, String filePath) throws IOException {UserInfo userInfo = userInfoService.selectUserByUserId(userId);UserStorageInfo userStorageInfo = userStorageInfoService.selectUserStorageInfoByUserId(userId);if(userInfo!=null&&userStorageInfo!=null){return new RestResult<>(0,"用户信息不存在",null);}String bucket = userInfo.getBucket();AmazonS3 s3 = s3Client.getS3Client(new String(decoder.decode(userStorageInfo.getAk())),new String(decoder.decode(userStorageInfo.getSk())));GetObjectRequest request = new GetObjectRequest(bucket,fileName);//获取s3发送的请求if(request!=null){S3Object object = s3.getObject(request);//获取文件大小long fSize = object.getObjectMetadata().getContentLength();InputStream inputStream = null;long pos = 0;File file = new File(filePath+fileName);OutputStream out;if(file.exists()){pos = file.length();request.setRange(pos);//设置请求头中的range参数out = new FileOutputStream(file,true);//如果已经存在文件,已追加的形式添加数据}else {file.createNewFile();out = new FileOutputStream(file);}try {inputStream = object.getObjectContent();//获取上述range字段范围的文件流inputStream.skip(pos);byte[] buffer = new byte[1024*100]; //以10M的速度进行下载int length = 0;while ((length = inputStream.read(buffer, 0, buffer.length)) != -1) {out.write(buffer, 0, length);// Thread.sleep(100); //调试的时候使用的}} catch (Exception e) {System.out.println("下载异常");}finally{try {if(null != out) out.flush();if(null != out) out.close();if(null != inputStream) inputStream.close();} catch (IOException e) {}}return new RestResult<>(0,file.length()==fSize?"下载完成":"下载未完成",file.length());}else {return new RestResult<>(0,"没有找到该文件",null);} }
-
如果说是一般的服务器的话,可以参考这篇博客