Aws S3 上传脚本

Aws S3 上传脚本
上传本地文件到 aws s3 并跳过已经上传过的文件

安装依赖

pip install boto3

代码

保存到 aws-s3.py

import os
import boto3
import hashlib

# 配置 AWS 凭证
aws_access_key_id = 'xxx'
aws_secret_access_key = 'xxx'
region_name = 'ap-southeast-2'  # 例如 'us-west-1'

# 初始化带凭证的 S3 客户端
session = boto3.Session(
    aws_access_key_id=aws_access_key_id,
    aws_secret_access_key=aws_secret_access_key,
    region_name=region_name
)
s3_client = session.client('s3')

def get_file_md5(file_path):
    """计算文件的 MD5 值"""
    with open(file_path, 'rb') as f:
        hash_md5 = hashlib.md5()
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

def upload_directory_to_s3(directory_path, bucket_name, s3_target_dir='', log_file_path='uploaded_files.log'):
    """上传目录下的所有文件到 S3,过滤已经上传的文件,并记录上传成功的文件"""
    uploaded_files = set()

    # 如果日志文件存在,则读取已经上传的文件记录
    if os.path.exists(log_file_path):
        with open(log_file_path, 'r') as log_file:
            for line in log_file:
                uploaded_files.add(line.strip())

    # 遍历目录下所有文件
    with open(log_file_path, 'a') as log_file:  # 打开日志文件,准备记录上传成功的文件
        for root, _, files in os.walk(directory_path):
            for file_name in files:
                file_path = os.path.join(root, file_name)
                # 使用正斜杠构建 S3 中的文件路径
                s3_key = os.path.relpath(file_path, directory_path).replace('\\', '/')
                if s3_target_dir:
                    s3_key = f"{s3_target_dir.rstrip('/')}/{s3_key}"

                # 跳过已经上传成功的文件
                if s3_key in uploaded_files:
                    print(f"{file_name} 已记录为上传成功,跳过上传")
                    continue

                # 获取文件的 MD5 值
                file_md5 = get_file_md5(file_path)

                # 检查文件是否已在 S3 中存在
                try:
                    obj = s3_client.head_object(Bucket=bucket_name, Key=s3_key)
                    if obj['ETag'].strip('"') == file_md5:
                        print(f"{file_name} 已存在于 S3,跳过上传")
                        continue
                except s3_client.exceptions.ClientError as e:
                    if e.response['Error']['Code'] != '404':
                        raise  # 如果不是文件不存在的错误,抛出异常
                
                # 上传文件
                print(f"正在上传 {file_name} 到 S3 路径 {s3_key}")
                s3_client.upload_file(file_path, bucket_name, s3_key)
                uploaded_files.add(s3_key)

                # 记录上传成功的文件
                log_file.write(f"{s3_key}\n")
    
    print("所有文件上传完成并记录成功上传的文件")

# 使用示例
directory_path = 'E:\\project\\heao\\shop.cubama.com_YdGzp.tar\\shop.cubama.com_YdGzp\\shop.cubama.com\\public\\download'  # 本地目录路径
bucket_name = 'shopmark-ap'  # S3 b
log_file_path = 'uploaded_files.log'  # 上传成功的文件记录日志路径
s3_target_dir = 'download'  # 上传到 S3 中的目标目录
upload_directory_to_s3(directory_path, bucket_name,s3_target_dir, log_file_path)

执行

python aws-s3.py

注意

因为使用的是windows平台,路径做了处理,如果是类unix平台,无需处理。

上传成功后的文件名会记录在 log_file_path 文件中。

python aws-s3.py

3 个赞

感谢大佬分享

2 个赞