我正在尝试使用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'];
}
}
答案 0 :(得分:0)
我知道这是一个比较老的问题,尽管似乎没有答案。
$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);
仅供参考:我已经排除了多范围选项...