批量打包下载阿里OSS文件

本文档介绍了一种从后端接口批量下载阿里OSS文件的方法,以解决前端逐个下载存在的用户体验不佳和可能的请求取消问题。通过创建ZipArchive对象,将多个文件内容添加到压缩包中,然后提供一次性下载,确保所有文件完整下载。这种方法提高了下载效率,降低了统计错误的风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有需求的地方就有方法,批量下载oss文件,上一章说的是从前端的角度实现批量一个个间断性下载,但是存在一定问题(1.用户体验不好,2.多次下载或弹窗需要修改浏览器配置,且有时候存在请求被取消的风险,操作人员如果不核实文件个数有时候很难发现这个问题,这对统计工作有一定风险),本文章是从后端接口,批量请求阿里oss获取下载文件内容,将获取到的数据打包一次性下载:

class TestOss extends BaseController
{
    //初测
	public function test()
	{
		$objectName = 'abc/2021/10/30/G20211030060001231.xlsx';
		$object = self::$oss->getObject($this->config['oss']['bucket'], $objectName);
  		$file = 'abc' . substr($objectName, strrpos($objectName, '.'));

		$fp = fopen ($file, 'w');
		fwrite($fp, $object);
		fclose($fp);
	}
    
    //打包下载
	public function testZip()
	{
		error_reporting(E_ALL);
		ini_set('display_errors', true);

		$zip = new ZipArchive;
		$tmpFileName = './tmpzip' . mt_rand(100, 999);
		$res = $zip->open($tmpFileName, ZipArchive::CREATE);
		var_dump(is_file($tmpFileName));

		$objectName = 'abc/1077/2021/10/30/G20211030060001231.xlsx';
		$object = self::$oss->getObject($this->config['oss']['bucket'], $objectName);
  		$file = 'abc' . substr($objectName, strrpos($objectName, '.'));

		if ($res === TRUE) {
		    $zip->addFromString($file, $object);
		    $zip->close();
		    $tarFile = 'abc.zip';
			var_dump(is_file($tmpFileName));
			$fileSize = filesize($tmpFileName);
			$fp = fopen($tmpFileName, "r");
			header("Content-type: application/octet-stream");
			header("Accept-Ranges: bytes");
			header("Accept-Length: " . $fileSize);
			header("Content-Disposition: attachment; filename=" . $tarFile); 
			$buffer = 1024;
			$fileCount = 0;
			while (!feof($fp) && $fileCount < $fileSize) {
				$fileCon = fread($fp, $buffer);
				$fileCount += $buffer;
				echo $fileCon;
			}
			fclose($fp);
			unlink($tmpFileName);
		} else {
		    echo 'failed';
		}
	}

}

(new TestOss())->testZip();

### Spring Boot 实现 OSS 文件打包下载 #### 使用场景描述 在现代Web应用程序中,文件管理和分发是一个常见的需求。通过将多个对象存储服务(OSS)中的文件打包并提供给用户下载,可以极大地提高用户体验和效率。 #### 准备工作 为了完成此操作,需先配置好Spring Boot项目与所选OSS之间的连接参数,并确保已安装必要的依赖项来处理压缩包创建以及网络请求发送等功能[^2]。 #### 创建ZIP压缩流 利用`java.util.zip.ZipOutputStream`类来进行ZIP格式的数据封装。该API允许逐个向档案内添加条目(即各个待打包的远程资源)。下面是一段用于初始化此类实例的方法: ```java private ZipOutputStream createZipStream(HttpServletResponse response, String zipFileName) throws IOException { response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zipFileName, StandardCharsets.UTF_8)); return new ZipOutputStream(response.getOutputStream()); } ``` #### 下载指定前缀下的所有文件 假设目标是从特定路径下获取一系列图片或其他类型的静态资产,则可以通过遍历这些项目的列表并将它们逐一加入到正在构建的ZIP容器之中。这里给出了一种可能的方式去检索来自阿里OSS的对象集合: ```java public void downloadFilesFromOSS(String bucketName, String prefix, HttpServletResponse response) throws Exception { // 初始化客户端和服务端交互所需的信息 final String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; final String accessKeyId = "<your-access-key-id>"; final String accessKeySecret = "<your-access-key-secret>"; try (OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret)) { ObjectListing objectListing; do { objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix(prefix)); for (OSSObjectSummary summary : objectListing.getObjectSummaries()) { InputStream inputStream = ossClient.getObject(bucketName, summary.getKey()).getObjectContent(); addEntryToZip(createZipStream(response, "files.zip"), summary.getKey(), IOUtils.toByteArray(inputStream)); inputStream.close(); } } while (objectListing.isTruncated()); } catch (Exception e) { throw new RuntimeException(e); } } // 添加单个文件入口到 ZIP 流中 private static void addEntryToZip(ZipOutputStream zos, String entryName, byte[] contentBytes) throws IOException { ZipEntry zipEntry = new ZipEntry(entryName.substring(entryName.lastIndexOf('/') + 1)); // 去掉目录结构只保留文件名 zos.putNextEntry(zipEntry); BufferedInputStream bis = null; try { bis = new BufferedInputStream(new ByteArrayInputStream(contentBytes)); int bytesRead; byte[] buffer = new byte[4096]; while ((bytesRead = bis.read(buffer)) != -1) { zos.write(buffer, 0, bytesRead); } } finally { if(bis!=null){ bis.close(); } zos.closeEntry(); } } ``` 上述代码片段展示了如何从阿里OSS批量读取符合条件的目标文件,并将其作为单独实体写入由HTTP响应体承载的一个临时性的ZIP数据流当中。注意,在实际部署之前应当妥善保管认证凭证信息而不是硬编码于源码之内;另外还需考虑并发访问控制等问题以保障系统的稳定性和安全性[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值