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

上传对象

在您将文件上传至 Amazon S3 时,文件会存储为 S3 对象。对象由文件数据和描述对象的元数据组成。一个存储桶中可以有无限量的对象。您需要拥有存储桶写入权限,才能将文件上传至 Amazon S3 存储桶。有关访问权限的更多信息,请参阅Amazon S3 的身份和访问管理

您可以将任何类型的文件上传至 S3 存储桶,包括图像、备份、数据、电影等。可使用 Amazon S3 控制台上传的文件的最大大小为 160 GB。要上传大于 160GB 的文件,请使用 Amazon Command Line Interface(Amazon CLI)、Amazon SDK 或 Amazon S3 REST API。

如果启用了版本控制的存储桶中已存在所上传对象的键名,则 Amazon S3 会创建该对象的另一个版本,而不是替换现有对象。有关启用版本控制的更多信息,请参阅在存储桶上启用版本控制

根据您要上传的数据大小,Amazon S3 提供以下选项:

  • 使用 Amazon SDK、REST API 或 Amazon CLI 在单个操作中上传对象 – 您可以在单个 PUT 操作中上传最大为 5GB 的单个对象。

  • 使用 Amazon S3 控制台上传单个对象 通过 Amazon S3 控制台,您可以上传最大 160GB 的单个对象。

  • 使用 Amazon SDK、REST API 或 Amazon CLI 分段上传对象您可以使用分段上传 API 操作来上传单个大型对象(最大大小为 5TB)。

    分段上传 API 操作旨在改进大型对象的上传体验。您可以分段上传对象。这些对象分段可以按任何顺序并行独立上传。您可以对大小在 5 MB 到 5 TB 范围内的对象使用分段上传。有关更多信息,请参阅 使用分段上传来上传和复制对象

当您上传对象时,默认情况下,将使用具有 Amazon S3 托管式密钥的服务器端加密(SSE-S3)自动加密对象。当您下载对象时,该对象将被解密。有关更多信息,请参阅为 Amazon S3 存储桶设置默认服务器端加密行为利用加密来保护数据

上传对象时,如果您想使用不同类型的默认加密,也可以在 S3 PUT 请求中指定具有 Amazon Key Management Service(Amazon KMS)密钥的服务器端加密(SSE-KMS),或者将目标存储桶中的默认加密配置设置为使用 SSE-KMS 来加密数据。有关 SSE-KMS 的更多信息,请参阅 使用 Amazon KMS (SSE-KMS) 指定服务器端加密。如果您希望使用其他账户拥有的 KMS 密钥,则您必须有权使用该密钥。有关 KMS 密钥的跨账户权限的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的创建其他账户可以使用的 KMS 密钥

如果您在 Amazon S3 中遇到拒绝访问(403 禁止访问)错误,请参阅排查 Amazon S3 中的拒绝访问(403 Forbidden)错误详细了解其常见原因。

上传对象

此过程介绍如何使用控制台将对象和文件夹上传到 Amazon S3 存储桶。

上传对象时,对象键名称是文件名和任何可选前缀。在 Amazon S3 控制台中,您可以创建文件夹来组织对象。在 Amazon S3 中,文件夹表示为出现在对象键名称中的前缀。如果您将单个对象上传到 Amazon S3 控制台中的文件夹,则文件夹名称将包含在对象键名称中。

例如,如果您将名为的对象上传 sample1.jpg 到名为 backup 的文件夹,则密钥名称为 backup/sample1.jpg。但是,对象会像 sample1.jpgbackup 文件夹中一样在控制台中显示。有关键名称的更多信息,请参阅 使用对象元数据

注意

如果在 Amazon S3 控制台中重命名对象或更改诸如存储类加密元数据等任何属性,将创建一个新对象来替换旧对象。如果启用 S3 版本控制,则会创建对象的新版本,而现有对象将变为旧版本。更改属性的角色也会成为新对象(或对象版本)的拥有者。

上传文件夹时,Amazon S3 会将所有文件和子文件夹从指定文件夹中上传至存储桶。然后,它会分配由上传文件名和文件夹名组成的对象键名。例如,如果您上传包含 /imagessample1.jpg 这两个文件的名为 sample2.jpg 的文件夹,则 Amazon S3 会上传这两个文件,然后分配相应的键名 images/sample1.jpgimages/sample2.jpg。键名包括作为前缀的文件夹名。Amazon S3 控制台仅显示最后一个“/”后面的键名部分。例如,在 images 文件夹中,images/sample1.jpgimages/sample2.jpg 对象显示为 sample1.jpgsample2.jpg

将文件夹和文件上传到 S3 存储桶
  1. 登录到Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. 在左侧导航窗格中,选择存储桶

  3. Buckets(存储桶) 列表中,请选择要将文件夹和文件上传到的存储桶的名称。

  4. 请选择 Upload(上传)。

  5. 上传窗口中,执行下列操作之一:

    • 将文件和文件夹拖放到上传窗口。

    • 选择添加文件添加文件夹,选择要上传的文件或文件夹,然后选择打开

  6. 要启用版本控制,请在目标下选择启用存储桶版本控制

  7. 要上传列出的文件和文件夹而不配置其他上传选项,请选择页面底部的上传

    Amazon S3 会上传您的对象和文件夹。上传完成后,您可以在上传:状态页面上看到成功消息。

配置其他对象属性
  1. 要更改访问控制列表权限,请选择 Permissions(权限)。

  2. Access control list (ACL) [访问控制列表 (ACL)]下,编辑权限。

    有关对象访问权限的信息,请参阅 使用 S3 控制台为对象设置 ACL 权限。您可以向公众(世界上的每一个人)授予对您的对象的读取访问权限,使其能够获取您正在上传的所有文件。但是,我们建议您不要更改公共读取访问的默认设置。授予公有读取访问权限适用于一小部分的使用案例(如存储桶用于网站时)。您始终可以在上传对象后更改对象权限。

  3. 要配置其他附加属性,请选择 Properties(属性)。

  4. 存储类下,为正在上传的文件选择存储类。

    有关存储类的更多信息,请参阅 了解和管理 Amazon S3 存储类

  5. 要更新对象的加密设置,请在服务器端加密设置下执行以下操作:

    1. 选择 Specify an encryption key(指定加密密钥)。

    2. 加密设置下,选择使用默认加密的存储桶设置覆盖默认加密的存储桶设置

    3. 如果您选择覆盖默认加密的存储桶设置,则必须配置以下加密设置。

      • 要使用由 Amazon S3 托管的密钥加密上传的文件,请选择 Amazon S3 托管式密钥(SSE-S3)

        有关更多信息,请参阅 使用具有 Amazon S3 托管式密钥的服务器端加密(SSE-S3)

      • 要使用存储在 Amazon Key Management Service(Amazon KMS)中的密钥加密上传的文件,请选择 Amazon Key Management Service 密钥(SSE-KMS)。然后,为 Amazon KMS 密钥选择以下选项之一:

        • 要从可用的 KMS 密钥列表中进行选择,请选择从您的 Amazon KMS keys 中进行选择,然后从可用密钥的列表中选择您的 KMS 密钥

          Amazon 托管式密钥(aws/s3)和您的客户自主管理型密钥都显示在此列表中。有关客户自主管理型密钥的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的客户密钥和 Amazon 密钥

        • 要输入 KMS 密钥 ARN,请选择输入 Amazon KMS key ARN,然后在显示的字段中输入您的 KMS 密钥 ARN。

        • 要在 Amazon KMS 控制台中创建新的客户自主管理型密钥,请选择创建 KMS 密钥

          有关创建 Amazon KMS key 的更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的创建密钥

        重要

        您只能使用与存储桶所在相同的 Amazon Web Services 区域中可用的 KMS 密钥。Amazon S3 控制台仅列出与存储桶位于同一区域中的前 100 个 KMS 密钥。要使用未列出的 KMS 密钥,您必须输入 KMS 密钥 ARN。如果您希望使用其他账户拥有的 KMS 密钥,则必须首先有权使用该密钥,然后必须输入相应的 KMS 密钥 ARN。

        Amazon S3 仅支持对称加密 KMS 密钥,不支持非对称 KMS 密钥。有关更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的确定对称和非对称 KMS 密钥

  6. 要使用其他校验和,请选择 On(打开)。然后对于 Checksum function(校验和函数),选择要使用的函数。Amazon S3 在收到整个对象后计算并存储校验和值。您可以使用 Precalculated value(预计算值)框来提供预先计算的值。这样,Amazon S3 会将您提供的值与其计算的值进行比较。如果两个值不匹配,Amazon S3 将生成错误。

    其他校验和使您能够指定要用于验证数据的校验和算法。有关其他校验和的更多信息,请参阅检查对象完整性

  7. 要向上传的所有对象添加标签,请选择 Add tag (添加标签)。在字段中输入标签名称。输入标签的值。

    对象标签为您提供了对存储进行分类的方法。每个标签都是一个键-值对。键和标签值区分大小写。对于每个对象,您最多可以有 10 个标签。标签键的长度最大可以为 128 个 Unicode 字符,标签值的长度最大可以为 255 个 Unicode 字符。有关对象标签的更多信息,请参阅 使用标签对存储进行分类

  8. 要添加元数据,请选择添加元数据

    1. 类型下,请选择系统定义用户定义

      对于系统定义元数据,您可以选择通用的 HTTP 标头,如 Content-TypeContent-Disposition。有关系统定义元数据的列表以及您能否添加值的信息,请参阅系统定义的对象元数据。以前缀 x-amz-meta- 开头的任何元数据都被视为用户定义的元数据。用户定义元数据会与对象存储在一起,并会在您下载该对象时返回。密钥及其值均必须符合 US-ASCII 标准。用户定义元数据最大可为 2 KB。如需详细了解系统定义和用户定义的元数据,请参阅使用对象元数据

    2. 对于,请选择一个键。

    3. 键入该键的值。

  9. 要上传对象,请选择上传

    Amazon S3 将上传您的对象。上传完成后,您可以在上传:状态页面上看到成功消息。

  10. 请选择 Exit(退出)。

您可以发送 PUT 请求,在单个操作中上传最大 5 GB 的对象。有关更多信息,请参阅 Amazon CLI 命令参考中的 PutObject 示例。

您可以发送 REST 请求以上传对象。您可以发送 PUT 请求以在单个操作中上传数据。有关更多信息,请参阅 PUT Object

您可以使用 Amazon SDK 在 Amazon S3 中上传对象。SDK 向您提供了包装程序库,使您可以更轻松地上传数据。有关信息,请参阅支持的 SDK 列表

以下是几个特色级 SDK 的示例:

.NET

以下 C# 代码示例将使用两个 PutObjectRequest 请求创建两个对象:

  • 第一个 PutObjectRequest 请求将文本字符串保存为示例对象数据。它还指定存储桶和对象键名。

  • 第二个 PutObjectRequest 请求通过指定文件名上传文件。此请求还指定 ContentType 标头和可选对象元数据(标题)。

有关设置和运行代码示例的信息,请参阅《适用于 .NET 的 Amazon SDK 开发人员指南》中的适用于 .NET 的 Amazon SDK 入门

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class UploadObjectTest { private const string bucketName = "*** bucket name ***"; // For simplicity the example creates two objects from the same file. // You specify key names for these objects. private const string keyName1 = "*** key name for first object created ***"; private const string keyName2 = "*** key name for second object created ***"; private const string filePath = @"*** file path ***"; private static readonly RegionEndpoint bucketRegion = RegionEndpoint.EUWest1; private static IAmazonS3 client; public static void Main() { client = new AmazonS3Client(bucketRegion); WritingAnObjectAsync().Wait(); } static async Task WritingAnObjectAsync() { try { // 1. Put object-specify only key name for the new object. var putRequest1 = new PutObjectRequest { BucketName = bucketName, Key = keyName1, ContentBody = "sample text" }; PutObjectResponse response1 = await client.PutObjectAsync(putRequest1); // 2. Put the object-set ContentType and add metadata. var putRequest2 = new PutObjectRequest { BucketName = bucketName, Key = keyName2, FilePath = filePath, ContentType = "text/plain" }; putRequest2.Metadata.Add("x-amz-meta-title", "someTitle"); PutObjectResponse response2 = await client.PutObjectAsync(putRequest2); } catch (AmazonS3Exception e) { Console.WriteLine( "Error encountered ***. Message:'{0}' when writing an object" , e.Message); } catch (Exception e) { Console.WriteLine( "Unknown encountered on server. Message:'{0}' when writing an object" , e.Message); } } } }
Java

以下示例将创建两个对象。第一个对象将一个文本字符串作为数据,第二对象是一个文件。该示例通过在对 AmazonS3Client.putObject() 的调用中直接指定存储桶名称、对象键和文本数据来创建第一个对象。该示例通过使用指定存储桶、对象键和文件路径的 PutObjectRequest 来创建第二个对象。PutObjectRequest 还指定 ContentType 标头和标题元数据。

有关创建和测试有效示例的说明,请参阅《Amazon SDK for Java 开发人员指南》中的入门

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import java.io.File; import java.io.IOException; public class UploadObject { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String stringObjKeyName = "*** String object key name ***"; String fileObjKeyName = "*** File object key name ***"; String fileName = "*** Path to file to upload ***"; try { // This code expects that you have AWS credentials set up per: // https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .build(); // Upload a text string as a new object. s3Client.putObject(bucketName, stringObjKeyName, "Uploaded String Object"); // Upload a file as a new object with ContentType and title specified. PutObjectRequest request = new PutObjectRequest(bucketName, fileObjKeyName, new File(fileName)); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("plain/text"); metadata.addUserMetadata("title", "someTitle"); request.setMetadata(metadata); s3Client.putObject(request); } 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(); } } }
JavaScript

以下示例将现有文件上传到特定区域中的 Amazon S3 存储桶。

import { readFile } from "node:fs/promises"; import { PutObjectCommand, S3Client, S3ServiceException, } from "@aws-sdk/client-s3"; /** * Upload a file to an S3 bucket. * @param {{ bucketName: string, key: string, filePath: string }} */ export const main = async ({ bucketName, key, filePath }) => { const client = new S3Client({}); const command = new PutObjectCommand({ Bucket: bucketName, Key: key, Body: await readFile(filePath), }); try { const response = await client.send(command); console.log(response); } catch (caught) { if ( caught instanceof S3ServiceException && caught.name === "EntityTooLarge" ) { console.error( `Error from S3 while uploading object to ${bucketName}. \ The object was too large. To upload objects larger than 5GB, use the S3 console (160GB max) \ or the multipart upload API (5TB max).`, ); } else if (caught instanceof S3ServiceException) { console.error( `Error from S3 while uploading object to ${bucketName}. ${caught.name}: ${caught.message}`, ); } else { throw caught; } } };
PHP

此示例将指导您使用 Amazon SDK for PHP 中的类上传大小最大为 5GB 的对象。对于更大的文件,您必须使用分段上传 API 操作。有关更多信息,请参阅 使用分段上传来上传和复制对象

有关适用于 Ruby 的 Amazon 开发工具包 API 的更多信息,请转到适用于 Ruby 的 Amazon 开发工具包 – 版本 2

例 — 通过上传数据在 Amazon S3 存储桶中创建对象

通过使用 putObject() 方法来上传数据,以下 PHP 示例在指定存储桶中创建对象。

require 'vendor/autoload.php'; use Aws\S3\Exception\S3Exception; use Aws\S3\S3Client; $bucket = '*** Your Bucket Name ***'; $keyname = '*** Your Object Key ***'; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1' ]); try { // Upload data. $result = $s3->putObject([ 'Bucket' => $bucket, 'Key' => $keyname, 'Body' => 'Hello, world!', 'ACL' => 'public-read' ]); // Print the URL to the object. echo $result['ObjectURL'] . PHP_EOL; } catch (S3Exception $e) { echo $e->getMessage() . PHP_EOL; }
Ruby

Amazon SDK for Ruby – 版本 3 通过两种方式将对象上传到 Amazon S3。第一种方式使用托管式文件上传程序,从而能更轻松地从磁盘上传任何大小的文件。使用托管文件上传程序方法:

  1. 创建 Aws::S3::Resource 类的实例。

  2. 按存储桶名称和键引用目标对象。位于存储桶中的对象具有可识别每个对象的唯一密钥。

  3. 在对象上调用 #upload_file

require 'aws-sdk-s3' # Wraps Amazon S3 object actions. class ObjectUploadFileWrapper attr_reader :object # @param object [Aws::S3::Object] An existing Amazon S3 object. def initialize(object) @object = object end # Uploads a file to an Amazon S3 object by using a managed uploader. # # @param file_path [String] The path to the file to upload. # @return [Boolean] True when the file is uploaded; otherwise false. def upload_file(file_path) @object.upload_file(file_path) true rescue Aws::Errors::ServiceError => e puts "Couldn't upload file #{file_path} to #{@object.key}. Here's why: #{e.message}" false end end # Example usage: def run_demo bucket_name = "amzn-s3-demo-bucket" object_key = "my-uploaded-file" file_path = "object_upload_file.rb" wrapper = ObjectUploadFileWrapper.new(Aws::S3::Object.new(bucket_name, object_key)) return unless wrapper.upload_file(file_path) puts "File #{file_path} successfully uploaded to #{bucket_name}:#{object_key}." end run_demo if $PROGRAM_NAME == __FILE__

Amazon SDK for Ruby - 版本 3 上传对象的第二种方式是使用 Aws::S3::Object#put 方法。如果对象为字符串或者为不是磁盘上的文件的 I/O 对象,此方式很有用。要使用此方法,请执行以下操作:

  1. 创建 Aws::S3::Resource 类的实例。

  2. 按存储桶名称和键引用目标对象。

  3. 调用 #put,从而传入字符串或 I/O 对象。

require 'aws-sdk-s3' # Wraps Amazon S3 object actions. class ObjectPutWrapper attr_reader :object # @param object [Aws::S3::Object] An existing Amazon S3 object. def initialize(object) @object = object end def put_object(source_file_path) File.open(source_file_path, 'rb') do |file| @object.put(body: file) end true rescue Aws::Errors::ServiceError => e puts "Couldn't put #{source_file_path} to #{object.key}. Here's why: #{e.message}" false end end # Example usage: def run_demo bucket_name = "amzn-s3-demo-bucket" object_key = "my-object-key" file_path = "my-local-file.txt" wrapper = ObjectPutWrapper.new(Aws::S3::Object.new(bucket_name, object_key)) success = wrapper.put_object(file_path) return unless success puts "Put file #{file_path} into #{object_key} in #{bucket_name}." end run_demo if $PROGRAM_NAME == __FILE__

防止上传具有相同键名称的对象

在对上传操作使用有条件写入来创建对象之前,您可以检查存储桶中是否存在该对象。这样可以防止覆盖现有数据。当上传时,有条件写入将验证存储桶中尚不存在具有相同键名称的现有对象。

可以将有条件写入用于 PutObjectCompleteMultipartUpload 请求。

有关有条件请求的更多信息,请参阅使用有条件请求向 S3 操作添加前提条件