Skip to content

SDK 使用

本文介绍如何在不同编程语言中使用 AWS S3 SDK。

🌐 支持的语言

AWS SDK 官方支持以下语言:

  • JavaScript (Node.js)
  • Python (Boto3)
  • Java
  • Go
  • Ruby
  • PHP
  • .NET (C#)
  • Rust
  • Swift
  • C++

📦 Node.js SDK

安装

bash
# AWS SDK v2
npm install aws-sdk

# AWS SDK v3 (推荐)
npm install @aws-sdk/client-s3

AWS SDK v2

javascript
const AWS = require('aws-sdk');

// 配置
AWS.config.update({
  region: 'us-east-1',
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
});

// 创建 S3 实例
const s3 = new AWS.S3();

// 基本操作
const basicOperations = async () => {
  // 列出 Buckets
  const buckets = await s3.listBuckets().promise();
  console.log(buckets.Buckets);
  
  // 上传文件
  await s3.putObject({
    Bucket: 'my-bucket',
    Key: 'file.txt',
    Body: 'Hello S3'
  }).promise();
  
  // 下载文件
  const obj = await s3.getObject({
    Bucket: 'my-bucket',
    Key: 'file.txt'
  }).promise();
  console.log(obj.Body.toString('utf-8'));
};

AWS SDK v3 (推荐)

javascript
const { S3Client, ListBucketsCommand, PutObjectCommand, GetObjectCommand } = require('@aws-sdk/client-s3');

// 创建客户端
const client = new S3Client({
  region: 'us-east-1',
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
  }
});

// 列出 Buckets
const listBuckets = async () => {
  const command = new ListBucketsCommand({});
  const response = await client.send(command);
  return response.Buckets;
};

// 上传文件
const uploadFile = async (bucket, key, body) => {
  const command = new PutObjectCommand({
    Bucket: bucket,
    Key: key,
    Body: body
  });
  
  const response = await client.send(command);
  return response;
};

// 下载文件
const getFile = async (bucket, key) => {
  const command = new GetObjectCommand({
    Bucket: bucket,
    Key: key
  });
  
  const response = await client.send(command);
  
  // 将 Stream 转换为 Buffer
  const chunks = [];
  for await (const chunk of response.Body) {
    chunks.push(chunk);
  }
  return Buffer.concat(chunks);
};

Express 集成

javascript
const express = require('express');
const multer = require('multer');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');

const app = express();
const upload = multer({ storage: multer.memoryStorage() });
const s3Client = new S3Client({ region: 'us-east-1' });

// 文件上传端点
app.post('/upload', upload.single('file'), async (req, res) => {
  try {
    const key = `uploads/${Date.now()}-${req.file.originalname}`;
    
    const command = new PutObjectCommand({
      Bucket: 'my-bucket',
      Key: key,
      Body: req.file.buffer,
      ContentType: req.file.mimetype
    });
    
    await s3Client.send(command);
    
    res.json({
      success: true,
      url: `https://my-bucket.s3.amazonaws.com/${key}`
    });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000);

🐍 Python SDK (Boto3)

安装

bash
pip install boto3

基本使用

python
import boto3
from botocore.exceptions import ClientError

# 创建客户端
s3 = boto3.client('s3',
    region_name='us-east-1',
    aws_access_key_id='your_access_key',
    aws_secret_access_key='your_secret_key'
)

# 列出 Buckets
response = s3.list_buckets()
for bucket in response['Buckets']:
    print(f"{bucket['Name']} - {bucket['CreationDate']}")

# 上传文件
def upload_file(file_name, bucket, object_name=None):
    if object_name is None:
        object_name = file_name
    
    try:
        s3.upload_file(file_name, bucket, object_name)
        print(f"File {file_name} uploaded to {bucket}/{object_name}")
    except ClientError as e:
        print(f"Error: {e}")

# 下载文件
def download_file(bucket, object_name, file_name):
    try:
        s3.download_file(bucket, object_name, file_name)
        print(f"File downloaded to {file_name}")
    except ClientError as e:
        print(f"Error: {e}")

# 上传字符串
s3.put_object(
    Bucket='my-bucket',
    Key='file.txt',
    Body=b'Hello S3'
)

# 读取对象
response = s3.get_object(Bucket='my-bucket', Key='file.txt')
content = response['Body'].read().decode('utf-8')
print(content)

使用 Resource API

python
# Resource API 更高级
s3 = boto3.resource('s3')

# 列出 Buckets
for bucket in s3.buckets.all():
    print(bucket.name)

# 上传文件
bucket = s3.Bucket('my-bucket')
bucket.upload_file('/path/to/file.txt', 'file.txt')

# 下载文件
bucket.download_file('file.txt', '/path/to/download/file.txt')

# 列出对象
for obj in bucket.objects.filter(Prefix='uploads/'):
    print(f"{obj.key} - {obj.size} bytes")

# 删除对象
obj = s3.Object('my-bucket', 'file.txt')
obj.delete()

Flask 集成

python
from flask import Flask, request, jsonify
import boto3
from werkzeug.utils import secure_filename
import uuid

app = Flask(__name__)
s3 = boto3.client('s3')

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({'error': 'No file provided'}), 400
    
    file = request.files['file']
    filename = secure_filename(file.filename)
    key = f"uploads/{uuid.uuid4()}-{filename}"
    
    try:
        s3.upload_fileobj(
            file,
            'my-bucket',
            key,
            ExtraArgs={'ContentType': file.content_type}
        )
        
        url = f"https://my-bucket.s3.amazonaws.com/{key}"
        return jsonify({'success': True, 'url': url})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)

☕ Java SDK

Maven 依赖

xml
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
    <version>1.12.x</version>
</dependency>

基本使用

java
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

public class S3Example {
    private static final String BUCKET_NAME = "my-bucket";
    private static AmazonS3 s3Client;
    
    public static void main(String[] args) {
        // 初始化客户端
        BasicAWSCredentials credentials = new BasicAWSCredentials(
            "your_access_key",
            "your_secret_key"
        );
        
        s3Client = AmazonS3ClientBuilder.standard()
            .withRegion("us-east-1")
            .withCredentials(new AWSStaticCredentialsProvider(credentials))
            .build();
        
        // 列出 Buckets
        List<Bucket> buckets = s3Client.listBuckets();
        for (Bucket bucket : buckets) {
            System.out.println(bucket.getName());
        }
        
        // 上传文件
        File file = new File("file.txt");
        s3Client.putObject(BUCKET_NAME, "file.txt", file);
        
        // 下载文件
        S3Object object = s3Client.getObject(BUCKET_NAME, "file.txt");
        S3ObjectInputStream inputStream = object.getObjectContent();
        
        // 删除对象
        s3Client.deleteObject(BUCKET_NAME, "file.txt");
    }
}

Spring Boot 集成

java
@Service
public class S3Service {
    @Value("${aws.s3.bucket}")
    private String bucketName;
    
    @Autowired
    private AmazonS3 s3Client;
    
    public String uploadFile(MultipartFile file) {
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
        
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());
            
            s3Client.putObject(
                bucketName,
                fileName,
                file.getInputStream(),
                metadata
            );
            
            return s3Client.getUrl(bucketName, fileName).toString();
        } catch (IOException e) {
            throw new RuntimeException("Failed to upload file", e);
        }
    }
    
    public byte[] downloadFile(String fileName) {
        S3Object object = s3Client.getObject(bucketName, fileName);
        try {
            return IOUtils.toByteArray(object.getObjectContent());
        } catch (IOException e) {
            throw new RuntimeException("Failed to download file", e);
        }
    }
}

🐹 Go SDK

安装

bash
go get github.com/aws/aws-sdk-go/service/s3

基本使用

go
package main

import (
    "bytes"
    "fmt"
    "os"
    
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    // 创建会话
    sess, _ := session.NewSession(&aws.Config{
        Region:      aws.String("us-east-1"),
        Credentials: credentials.NewStaticCredentials("key", "secret", ""),
    })
    
    // 创建 S3 服务客户端
    svc := s3.New(sess)
    
    // 列出 Buckets
    result, _ := svc.ListBuckets(nil)
    for _, bucket := range result.Buckets {
        fmt.Printf("Bucket: %s\n", *bucket.Name)
    }
    
    // 上传文件
    file, _ := os.Open("file.txt")
    defer file.Close()
    
    _, err := svc.PutObject(&s3.PutObjectInput{
        Bucket: aws.String("my-bucket"),
        Key:    aws.String("file.txt"),
        Body:   file,
    })
    if err != nil {
        fmt.Println("Upload error:", err)
    }
    
    // 下载文件
    resp, _ := svc.GetObject(&s3.GetObjectInput{
        Bucket: aws.String("my-bucket"),
        Key:    aws.String("file.txt"),
    })
    defer resp.Body.Close()
    
    buf := new(bytes.Buffer)
    buf.ReadFrom(resp.Body)
    fmt.Println(buf.String())
}

Gin 集成

go
package main

import (
    "github.com/gin-gonic/gin"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3/s3manager"
)

func main() {
    r := gin.Default()
    
    sess, _ := session.NewSession(&aws.Config{
        Region: aws.String("us-east-1"),
    })
    uploader := s3manager.NewUploader(sess)
    
    r.POST("/upload", func(c *gin.Context) {
        file, _ := c.FormFile("file")
        f, _ := file.Open()
        defer f.Close()
        
        result, err := uploader.Upload(&s3manager.UploadInput{
            Bucket: aws.String("my-bucket"),
            Key:    aws.String(file.Filename),
            Body:   f,
        })
        
        if err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        
        c.JSON(200, gin.H{
            "success": true,
            "url":     result.Location,
        })
    })
    
    r.Run(":8080")
}

🔧 SDK 配置

凭证配置

1. 环境变量

bash
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_DEFAULT_REGION=us-east-1

2. 配置文件

bash
# ~/.aws/credentials
[default]
aws_access_key_id = your_access_key
aws_secret_access_key = your_secret_key

[production]
aws_access_key_id = prod_access_key
aws_secret_access_key = prod_secret_key

# ~/.aws/config
[default]
region = us-east-1

[profile production]
region = us-west-2

3. IAM 角色(推荐用于 EC2/Lambda)

javascript
// 无需显式配置凭证
const s3 = new AWS.S3({ region: 'us-east-1' });

自定义配置

javascript
// Node.js
const s3 = new AWS.S3({
  region: 'us-east-1',
  accessKeyId: 'key',
  secretAccessKey: 'secret',
  httpOptions: {
    timeout: 300000,  // 5分钟超时
    connectTimeout: 5000
  },
  maxRetries: 3,  // 重试次数
  s3ForcePathStyle: false,
  signatureVersion: 'v4'
});
python
# Python
s3 = boto3.client('s3',
    region_name='us-east-1',
    config=boto3.session.Config(
        signature_version='s3v4',
        retries={'max_attempts': 3},
        connect_timeout=5,
        read_timeout=300
    )
)

💡 最佳实践

1. 错误处理

javascript
// Node.js
const uploadWithRetry = async (params, maxRetries = 3) => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await s3.upload(params).promise();
    } catch (err) {
      if (i === maxRetries - 1) throw err;
      console.log(`Retry ${i + 1}/${maxRetries}`);
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
};

2. 连接池

javascript
// 复用 S3 客户端实例
const s3 = new AWS.S3({
  httpOptions: {
    agent: new https.Agent({
      keepAlive: true,
      maxSockets: 50
    })
  }
});

3. 进度监控

javascript
const uploadWithProgress = (params) => {
  const upload = s3.upload(params);
  
  upload.on('httpUploadProgress', (progress) => {
    const percentage = (progress.loaded / progress.total) * 100;
    console.log(`Progress: ${percentage.toFixed(2)}%`);
  });
  
  return upload.promise();
};

📖 相关资源


下一步:学习 权限管理 🔐