如何使用AWS getObject和Range下载LARGE文件



我正在尝试使用getObject方法从AWS S3下载大文件。但对于大文件,页面会下降。我如何使用该范围来完整下载文件的部分?

function DownloadContent($keyName) {
    $store = array();
    require(__DIR__ . '/../config/s3Config.php');
    if (!$this->s3Client) {
        $this->s3Client = S3Client::factory(array(
                    'key' => $store['s3']['key'],
                    'secret' => $store['s3']['secret']
        ));
    }
    foreach ($keyName as $key => $row) {
        $varFileName = explode('/', $row);
        $bucket = 'my-bucket-name';
        $result = $this->s3Client->getObject(array(
            'Bucket' => $bucket,
            'Key' => $row
        ));
        header("Content-Type: {$result['ContentType']}");
        header("Content-Disposition: attachment; filename="{$varFileName[2]}"");
        header('Expires: 0');header("X-Sendfile: $varFileName[2]");
        echo $result['Body'];
    }
}

我知道这是一个相当古老的问题,但似乎没有答案。

  • stream_copy_to_stream()应该有助于提高内存使用率
  • 流是可查找的,在使用PHP发送文件时,按照可恢复下载中所述设置标题?应该还可以
$bucket_name = 'my-bucket';
$object_key = 'object-key';
// initialize the S3 client
$client = new S3Client(...);
// register the stream
$client->registerStreamWrapper();
// get the file size
$file_size = filesize('s3://'.$bucket_name.'/'.$object_key);
// get the meta data
$meta_data = $client->headObject([
    'Bucket' => $bucket_name,
    'Key' => $object_key
]);
// get the offset & length
$offset = 0;
$length = $file_size;
$partial_content = false;
if(isset($_SERVER['HTTP_RANGE'])) {
    // the first 500 bytes: bytes=0-499
    // the second 500 bytes: bytes=500-999
    // all bytes except for the first 500 until the end of document: bytes=500-
    // the last 500 bytes of the document: bytes=-500
    preg_match('{bytes=(d+)?-(d+)?(,)?}i', $_SERVER['HTTP_RANGE'], $matches);
    if(empty($matches[3])) {
        $partial_content = true;
        $offset = (!empty($matches[1])) ? intval($matches[1]) : 0;
        $length = (!empty($matches[2])) ? intval($matches[2]) : $file_size;
        $length -= $offset;
    }
}
// set the headers for partial content
if($partial_content === true) {
    header('HTTP/1.1 206 Partial Content');
    header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $file_size);
}
// set the regular HTTP headers
header('Content-Type: '.$meta_data['ContentType']);
header('Content-Length: '.$file_size);
header('Content-Disposition: attachment; filename="'.basename($object_key).'"');
header('Accept-Ranges: bytes');
// open a S3 stream to the file
$s3file = fopen('s3://'.$bucket_name.'/'.$object_key, 'rb');
if(!$s3file) {
    throw new Exception('Error opening S§ stream for reading!');
}
// open an output stream
$out = fopen('php://output', 'wb');
// copy data from the S3 stream to the output stream
fseek($s3file, $offset);
stream_copy_to_stream($s3file, $out, $length);
// close the streams
fclose($out);
fclose($s3file);

仅供参考:我已经排除了多范围选项。。。

最新更新