如何将文件从 AWS S3 流式传输到 Zip 中

Art*_*gio 5 php streaming zip amazon-s3 amazon-web-services

我正在使用PHP Flysystem包从我的AWS S3存储桶流式传输内容。特别是,我正在使用$filesystem->readStream.

我的问题

当我流式传输文件时,它以myzip.zip 结尾并且大小是正确的,但是当解压缩它时,它变成了myzip.zip.cpgz。这是我的原型:

header('Pragma: no-cache');
header('Content-Description: File Download');
header('Content-disposition: attachment; filename="myZip.zip"');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
$s3 = Storage::disk('s3'); // Laravel Syntax
echo $s3->readStream('directory/file.jpg');
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

副题

当我流式传输这样的文件时,是否:

  1. 完全下载到我服务器的 RAM 中,然后传输到客户端,或者
  2. 它是否会以块的形式保存在缓冲区中,然后传输到客户端?

基本上,如果我有数十 GB 的数据被流式传输,我的服务器是否会负担沉重?

bra*_*sen 2

您当前正在将 的原始内容转储为directory/file.jpgzip(其中 jpg 不是 zip)。您需要使用这些内容创建一个 zip 文件。

代替

echo $s3->readStream('directory/file.jpg');
Run Code Online (Sandbox Code Playgroud)

使用Zip 扩展名尝试以下操作:

// use a temporary file to store the Zip file
$zipFile = tmpfile();
$zipPath = stream_get_meta_data($zipFile)['uri'];
$jpgFile = tmpfile();
$jpgPath = stream_get_meta_data($jpgFile)['uri'];

// Download the file to disk
stream_copy_to_stream($s3->readStream('directory/file.jpg'), $jpgFile);

// Create the zip file with the file and its contents
$zip = new ZipArchive();
$zip->open($zipPath);
$zip->addFile($jpgPath, 'file.jpg');
$zip->close();

// export the contents of the zip
readfile($zipPath);
Run Code Online (Sandbox Code Playgroud)

使用tmpfilestream_copy_to_stream,它将以块的形式将其下载到磁盘上的临时文件中,而不是下载到 RAM 中