下载对象 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

下载对象

本部分介绍如何从 S3 桶下载对象。

下载对象时需收取数据传输费。有关 Amazon S3 功能和定价的信息,请参阅 Amazon S3

您可以使用 Amazon S3 控制台为每个请求下载一个对象。要下载多个对象,请使用 Amazon CLI、Amazon 软件开发工具包或 REST API。

当您以编程方式下载对象时,其元数据将在响应标头中返回。有时,您希望覆盖 GET 响应中返回的特定响应标头值。例如,您可能覆盖 GET 请求中的 Content-Disposition 响应标头值。REST GET Object API(参阅 GET Object)允许您指定 GET 请求中的查询字符串参数以覆盖这些值。适用于 Java、.NET 和 PHP 的 Amazon 软件开发工具包同样提供了必需的对象,您可以使用它们在 GET 请求中指定这些响应标头的值。

检索使用服务器端加密进行加密存储的对象时,必须提供合适的请求标头。有关更多信息,请参阅利用加密来保护数据

本节介绍如何使用 Amazon S3 控制台使用预签名 URL 从 S3 桶下载对象。

注意
  • 一次只能下载一个对象。

  • 使用 Amazon S3 控制台下载的键名以句点“.”结尾的对象将从下载对象的键名中删除句点“.”。要下载键名以句点“.”结尾并保留在下载对象中的对象,必须使用 Amazon Command Line Interface (Amazon CLI)、Amazon 软件开发工具包或 REST API。对于 Amazon CLI、REST API 以及 Amazon SDK 信息以及示例,请参阅下载对象

从 S3 桶下载对象
  1. 登录到 Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. Buckets(桶) 列表中,请选择要从中下载对象的桶的名称。

  3. 您可以使用以下任一方式从 S3 桶下载对象:

    • 选择对象,然后从 Actions(操作)菜单中选择 Download(下载),或者,如果想要将对象下载到特定文件夹,请选择 Download as(下载为)。

    • 如果要下载特定版本的对象,请选择 Show versions(显示版本)按钮。选择所需的对象版本,然后从 Actions(操作)菜单中选择 Download(下载),或者,如果想要将对象下载到特定文件夹,请选择 Download as(下载为)。

SDK for Java

当您通过 Amazon SDK for Java 下载对象时,Amazon S3 将返回该对象的所有元数据以及从中读取该对象内容的输入流。

要检索对象,请执行以下操作:

  • 执行 AmazonS3Client.getObject() 方法,并在请求中提供桶名称和对象键。

  • 执行 S3Object 实例方法之一以处理输入流。

注意

您的网络连接将保持打开状态,直到您读取所有数据或关闭输入流。建议您尽快读取流的内容。

下面是您可能使用的一些变体:

  • 您可以通过在请求中指定所需的字节范围来仅读取部分对象数据,而不是读取整个对象。

  • 您可以选择性地通过使用 ResponseHeaderOverrides 对象并设置相应的请求属性来覆盖响应标头值。例如,您可以使用此功能指示应该将对象下载到具有与对象键名不同的文件名的文件中。

下面的例子通过三种方式从 Amazon S3 桶中检索对象:作为完整的对象、作为来自该对象的一系列字节以及作为包含被覆盖的响应标头值的完整对象。有关从 Amazon S3 中获取对象的更多信息,请参阅 GET Object。有关创建和测试有效示例的说明,请参阅测试 Amazon S3 Java 代码示例

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ResponseHeaderOverrides; import com.amazonaws.services.s3.model.S3Object; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class GetObject2 { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String key = "*** Object key ***"; S3Object fullObject = null, objectPortion = null, headerOverrideObject = null; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); // Get an object and print its contents. System.out.println("Downloading an object"); fullObject = s3Client.getObject(new GetObjectRequest(bucketName, key)); System.out.println("Content-Type: " + fullObject.getObjectMetadata().getContentType()); System.out.println("Content: "); displayTextInputStream(fullObject.getObjectContent()); // Get a range of bytes from an object and print the bytes. GetObjectRequest rangeObjectRequest = new GetObjectRequest(bucketName, key) .withRange(0, 9); objectPortion = s3Client.getObject(rangeObjectRequest); System.out.println("Printing bytes retrieved."); displayTextInputStream(objectPortion.getObjectContent()); // Get an entire object, overriding the specified response headers, and print the object's content. ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides() .withCacheControl("No-cache") .withContentDisposition("attachment; filename=example.txt"); GetObjectRequest getObjectRequestHeaderOverride = new GetObjectRequest(bucketName, key) .withResponseHeaders(headerOverrides); headerOverrideObject = s3Client.getObject(getObjectRequestHeaderOverride); displayTextInputStream(headerOverrideObject.getObjectContent()); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } finally { // To ensure that the network connection doesn't remain open, close any open input streams. if (fullObject != null) { fullObject.close(); } if (objectPortion != null) { objectPortion.close(); } if (headerOverrideObject != null) { headerOverrideObject.close(); } } } private static void displayTextInputStream(InputStream input) throws IOException { // Read the text input stream one line at a time and display each line. BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String line = null; while ((line = reader.readLine()) != null) { System.out.println(line); } System.out.println(); } }
SDK for JavaScript

以下 SDK for JavaScript 代码示例从 Amazon S3 桶检索对象。当您运行代码时,桶内的对象将返回为 ReadableStream,然后将其转换为字符串。有关从 Amazon S3 中获取对象的更多信息,请参阅 GET Object。有关创建和测试有效示例的说明,请参阅测试 Amazon SDK for JavaScript

import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"; const client = new S3Client({}) export const main = async () => { const command = new GetObjectCommand({ Bucket: "test-bucket", Key: "hello-s3.txt" }); try { const response = await client.send(command); // The Body object also has 'transformToByteArray' and 'transformToWebStream' methods. const str = await response.Body.transformToString(); console.log(str); } catch (err) { console.error(err); } };
.NET

当下载某个对象时,您将获得该对象的所有元数据以及从中读取内容的流。您应该尽快读取流的内容,因为数据直接源自 Amazon S3,在您读取所有数据或关闭输入流之前,您的网络连接将保持打开状态。您通过执行以下操作来获取对象:

  • 通过在请求中提供桶名称和对象键来执行 getObject 方法。

  • 执行 GetObjectResponse 方法之一以处理流。

下面是您可能使用的一些变体:

  • 您可以通过在请求中指定字节范围来仅读取部分对象,而不是读取整个对象,如以下 C# 示例所示:

    GetObjectRequest request = new GetObjectRequest { BucketName = bucketName, Key = keyName, ByteRange = new ByteRange(0, 10) };
  • 在检索对象时,您可以选择通过使用 下载对象 对象并设置相应的请求属性来替换响应标头值(参阅 ResponseHeaderOverrides)。以下 C# 代码示例演示了如何执行此操作。例如,您可以使用此功能指示应该将对象下载到具有与对象键名不同的文件名的文件中。

    GetObjectRequest request = new GetObjectRequest { BucketName = bucketName, Key = keyName }; ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides(); responseHeaders.CacheControl = "No-cache"; responseHeaders.ContentDisposition = "attachment; filename=testing.txt"; request.ResponseHeaderOverrides = responseHeaders;

以下 C# 代码示例从 Amazon S3 桶检索数据元。通过该响应,示例将读取使用 GetObjectResponse.ResponseStream 属性的对象数据。该示例还介绍如何使用 GetObjectResponse.Metadata 集合读取对象元数据。如果您检索的对象具有 x-amz-meta-title 元数据,则该代码会打印元数据值。

有关如何创建和测试有效示例的说明,请参阅 运行 Amazon S3 .NET 代码示例

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.IO; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class GetObjectTest { private const string bucketName = "*** bucket name ***"; private const string keyName = "*** object key ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 client; public static void Main() { client = new AmazonS3Client(bucketRegion); ReadObjectDataAsync().Wait(); } static async Task ReadObjectDataAsync() { string responseBody = ""; try { GetObjectRequest request = new GetObjectRequest { BucketName = bucketName, Key = keyName }; using (GetObjectResponse response = await client.GetObjectAsync(request)) using (Stream responseStream = response.ResponseStream) using (StreamReader reader = new StreamReader(responseStream)) { string title = response.Metadata["x-amz-meta-title"]; // Assume you have "title" as medata added to the object. string contentType = response.Headers["Content-Type"]; Console.WriteLine("Object metadata, Title: {0}", title); Console.WriteLine("Content type: {0}", contentType); responseBody = reader.ReadToEnd(); // Now you process the response body. } } catch (AmazonS3Exception e) { // If bucket or object does not exist Console.WriteLine("Error encountered ***. Message:'{0}' when reading object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when reading object", e.Message); } } } }
PHP

本主题介绍如何使用 Amazon SDK for PHP 中的类检索 Amazon S3 对象。您可以检索整个对象或对象中的字节范围。我们假定您已按照 使用Amazon SDK for PHP和运行 PHP 示例 的说明执行操作,并且正确安装了 Amazon SDK for PHP。

在检索对象时,您可以选择覆盖响应标头值,方法是将响应键、ResponseContentTypeResponseContentLanguageResponseContentDispositionResponseCacheControlResponseExpires 添加到 getObject() 方法,如以下 PHP 代码示例所示:

$result = $s3->getObject([ 'Bucket' => $bucket, 'Key' => $keyname, 'ResponseContentType' => 'text/plain', 'ResponseContentLanguage' => 'en-US', 'ResponseContentDisposition' => 'attachment; filename=testing.txt', 'ResponseCacheControl' => 'No-cache', 'ResponseExpires' => gmdate(DATE_RFC2822, time() + 3600), ]);

有关检索对象的更多信息,请参阅 下载对象

以下 PHP 示例将检索对象,并在浏览器中显示对象的内容。该示例演示如何使用 getObject() 方法。有关运行本指南中的 PHP 示例的信息,请参阅 运行 PHP 示例

require 'vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; $bucket = '*** Your Bucket Name ***'; $keyname = '*** Your Object Key ***'; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1' ]); try { // Get the object. $result = $s3->getObject([ 'Bucket' => $bucket, 'Key' => $keyname ]); // Display the object in the browser. header("Content-Type: {$result['ContentType']}"); echo $result['Body']; } catch (S3Exception $e) { echo $e->getMessage() . PHP_EOL; }

您可以使用 Amazon 软件开发工具包从桶检索对象键。然而,如果您的应用程序需要它,则可以直接发送 REST 请求。您可以发送 GET 请求以检索对象键。

有关请求和响应格式的详细信息,请参阅 Get Object

以下示例将向您展示如何使用 Amazon CLI 从 Amazon S3 下载对象。此命令从桶 DOC-EXAMPLE-BUCKET1 获取对象 dir/my_images.tar.bz2。对象将输出到名为 my_downloaded_image.tar.bz2 的文件。有关更多信息和示例,请参阅 Amazon CLI 命令参考指南中的 get-object

aws s3api get-object --bucket DOC-EXAMPLE-BUCKET1 --key dir/my_images.tar.bz2 my_downloaded_image.tar.bz2