本页导航
article
文件下载
AI摘要
腾讯云 COS 文件下载实现,获取文件下载输入流的方法
获取到文件下载输入流
后端
CosManager.java
/**
* 下载对象
*
* @param key 唯一键
* @return 文件的字节数组
*/
public byte[] getObject(String key)throws CosClientException, IOException {
// 调用 COS 接口之前必须保证本进程存在一个 COSClient 实例,如果没有则创建
COSClient cosClient = createCOSClient();
//下载文件
GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
COSObjectInputStream cosObjectInput = null;
try {
COSObject cosObject = cosClient.getObject(getObjectRequest);
cosObjectInput = cosObject.getObjectContent();
} catch (CosServiceException e) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "下载失败");
}
// 处理下载到的流
// 这里是直接读取,按实际情况来处理
byte[] bytes = null;
try {
bytes = IOUtils.toByteArray(cosObjectInput);
} catch (IOException e) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据读取失败");
} finally {
// 用完流之后一定要调用 close()
cosObjectInput.close();
}
// 在流没有处理完之前,不能关闭 cosClient
// 确认本进程不再使用 cosClient 实例之后,关闭即可
cosClient.shutdown();
return bytes;
}
CosController.java
/**
* 文件下载
*
* @param uploadFileRequest 文件对象
* @param request 请求
* @return 用户id
*/
@Operation(summary = "文件下载")
@PostMapping("/download")
public BaseResponse<byte[]> download(@RequestBody UploadFileRequest uploadFileRequest, HttpServletRequest request) {
String filepath = uploadFileRequest.getFilepath();
userService.getLoginUser(request);
String key = filepath.replace(HOST, "");
String fileName = StringUtils.substringAfterLast(key, "/");
String fileExtension = StringUtils.substringAfter(fileName, ".");
try {
boolean objectExists = cosClient.doesObjectExist(bucket, key);
if (!objectExists) {
// 如果对象不存在,返回相应的响应
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "对象不存在");
}
// 调用cosManager.download()下载文件
byte[] data = cosManager.getObject(key);
// 推断MIME类型
MediaType mediaType;
switch (fileExtension.toLowerCase()) {
case "pdf":
mediaType = MediaType.APPLICATION_PDF;
break;
case "jpg":
mediaType = MediaType.IMAGE_JPEG;
break;
// 添加更多文件类型和对应的MediaType
default:
mediaType = MediaType.APPLICATION_OCTET_STREAM;
break;
}
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(mediaType);
headers.setContentDispositionFormData("attachment", fileName);
return ResultUtils.success(data, fileName, mediaType.getType());
} catch (Exception e) {
log.error("file download error, filepath = " + filepath, e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "下载失败:"+ e.getMessage());
}
}
前端
基于vue3 + ts + elementplus
接口
/**
* 文件下载
* @param requestBody
* @returns BaseResponseByte<any> OK
* @throws ApiError
*/
public static download(
requestBody: UploadFileRequest,
): CancelablePromise<BaseResponseByte> {
return __request(OpenAPI, {
method: 'POST',
url: '/cos/download',
body: requestBody,
mediaType: 'application/json',
});
}
使用
html
<el-button type="primary" @click="downloadFile">下载</el-button>
ts
function base64toFile(base64Data:any, filename:any, mimeType:any) {
// 创建一个Base64字符串转换为Uint8Array的函数
function base64ToArrayBuffer(base64:any) {
const binaryString = window.atob(base64);
const length = binaryString.length;
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
// 将Base64数据转换为Uint8Array
const uint8Array = base64ToArrayBuffer(base64Data);
// 创建Blob对象
const blob = new Blob([uint8Array], { type: mimeType });
// 创建一个URL对象,用于文件下载
const url = window.URL.createObjectURL(blob);
// 创建一个链接元素并触发下载
const a = document.createElement("a");
a.href = url;
a.download = filename || "file"; // 可以指定文件名,如果未提供默认为"file"
document.body.appendChild(a);
a.click();
// 释放URL对象
window.URL.revokeObjectURL(url);
}
function downloadFile({ $index, row }) {
return new Promise((resolve, reject) => {
CosControllerService.download({
filepath: row.key
}).then(res => {
base64toFile(res.data, res.key, res.mimeType);
resolve(res.data)
}).catch(error => {
reject(error)
})
})
}
通过路径链接下载
后端
官方文档介绍了 2 种文件下载方式。一种是直接下载 COS 的文件到后端服务器(适合服务器端处理文件),另一种是获取到文件下载输入流(适合返回给前端用户)。
参考官方文档:
- https://cloud.tencent.com/document/product/436/65937
- https://cloud.tencent.com/document/product/436/10199#.E4.B8.8B.E8.BD.BD.E5.AF.B9.E8.B1.A1
其实还有第三种“下载方式”,直接通过路径链接访问,适用于单一的、可以被用户公开访问的资源,比如用户头像、本项目中的代码生成器图片。
但是对于本项目中的代码生成器产物包文件,更建议通过后端服务器从 COS 下载文件并返回给前端,这样可以在后端限制只有登录用户才能下载。
CosManager
在 CosManager 中新增对象下载方法,根据对象的 key 获取存储信息:
/**
* 下载对象
*
* @param key 唯一键
* @return
*/
public COSObject getObject(String key) {
GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
return cosClient.getObject(getObjectRequest);
}
CosController
核心流程是根据路径获取到 COS 文件对象,然后将文件对象转换为文件流,并写入到 Servlet 的 Response 对象中。注意要设置文件下载专属的响应头。
加载中...
最后更新于 2026-02-18 18:09