使用 rclone 批量导出 Cloudflare R2 存储文件

October, 23rd 2025 8 min read

背景

Cloudflare R2 是一个兼容 S3 的对象存储服务。虽然 Cloudflare 提供了 wrangler CLI 工具,但它不支持批量下载文件,只能下载单个文件。要批量导出 R2 存储桶中的文件,需要使用第三方工具。

官方推荐方案:使用 rclone

根据 Cloudflare 官方文档,批量操作 R2 文件的推荐方式是使用 rclone,一个开源的云存储同步工具。

完整操作步骤

第一步:安装 rclone

macOS:

bash
1
      brew install rclone
    

Linux:

bash
1
      curl https://rclone.org/install.sh | sudo bash
    

Windows:rclone 官网 下载安装包

第二步:创建 R2 API Token

  1. 登录 Cloudflare Dashboard
  2. 进入 R2 管理页面:https://dash.cloudflare.com/{account_id}/r2/overview
  3. 点击右上角 “Manage R2 API Tokens”
  4. 点击 “Create API Token”
  5. 配置权限:
    • Token name: 随意命名(例如:r2-export-token
    • Permissions:
      • Object Read(读取对象)
      • Object List(列出对象)
    • Bucket scope: 选择需要访问的存储桶,或选择 “All buckets”
  6. 点击 “Create API Token”
  7. 重要:复制并保存以下信息(只会显示一次):
    • Access Key ID
    • Secret Access Key
    • Endpoint URL(通常格式为:https://{account_id}.r2.cloudflarestorage.com

第三步:配置 rclone

运行配置命令:

bash
1
      rclone config
    

按照提示完成配置:

plaintext
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
      1. 选择操作
n) New remote
> n

2. 输入 remote 名称
name> r2prod

3. 选择存储类型
Storage> s3
(输入数字或直接输入 s3)

4. 选择 S3 提供商
provider> Cloudflare
(选择 Cloudflare 或输入对应数字)

5. 选择认证方式
env_auth> false
(选择手动输入凭据)

6. 输入 Access Key ID
access_key_id> [粘贴你的 Access Key ID]

7. 输入 Secret Access Key
secret_access_key> [粘贴你的 Secret Access Key]

8. 区域设置
region> auto
(Cloudflare R2 使用 auto)

9. Endpoint 设置
endpoint> https://{account_id}.r2.cloudflarestorage.com
(替换 {account_id} 为你的实际 Account ID)

10. Location constraint
location_constraint>
(留空,直接回车)

11. ACL 设置
acl> private

12. 服务端加密
server_side_encryption>
(留空,直接回车)

13. 存储类别
storage_class>
(留空,直接回车)

14. 高级配置
Edit advanced config? (y/n)
> n

15. 确认配置
y) Yes this is OK (default)
> y
    

第四步:测试连接

验证 rclone 配置是否正确:

bash
12345
      # 列出所有存储桶
rclone lsd r2prod:

# 列出特定存储桶的内容
rclone ls r2prod:your-bucket-name --max-depth 1
    

第五步:下载文件

基本用法

下载整个存储桶:

bash
1
      rclone copy r2prod:bucket-name ./local-directory
    

下载特定前缀的文件:

bash
1
      rclone copy r2prod:bucket-name/prefix/ ./local-directory
    

推荐参数

使用以下参数以获得更好的性能和用户体验:

bash
1234567
      rclone copy r2prod:bucket-name/prefix/ ./output-directory \
  --progress \              # 显示进度
  --transfers 8 \           # 并行传输数(默认 4)
  --checkers 16 \           # 并行检查数(默认 8)
  --stats 2s \              # 每 2 秒更新统计
  --stats-one-line \        # 单行显示统计
  --s3-no-check-bucket      # 跳过存储桶检查(提升性能)
    

常用场景

只下载新文件或已修改的文件(增量下载):

bash
1
      rclone copy r2prod:bucket/path/ ./local-path --progress
    

同步(删除本地多余文件):

bash
1
      rclone sync r2prod:bucket/path/ ./local-path --progress
    

⚠️ 注意:sync 会删除本地目录中不存在于 R2 的文件!

预览将要下载的文件(不实际下载):

bash
1
      rclone copy r2prod:bucket/path/ ./local-path --dry-run
    

自动化脚本示例

创建一个便捷的导出脚本 export-r2-files.sh

bash
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
      #!/bin/bash
# 从 Cloudflare R2 批量导出文件

set -e

# 配置
REMOTE_NAME="r2prod"
BUCKET_NAME="your-bucket-name"
PREFIX="${1:-workflow-outputs/}"
OUTPUT_DIR="${2:-./r2-exports}"

echo "🚀 Starting R2 files export..."
echo "📦 Bucket: ${BUCKET_NAME}"
echo "📁 Prefix: ${PREFIX}"
echo "💾 Output: ${OUTPUT_DIR}"
echo ""

# 检查 rclone 是否安装
if ! command -v rclone &> /dev/null; then
    echo "❌ rclone is not installed!"
    echo "Install it with: brew install rclone"
    exit 1
fi

# 检查远程是否配置
if ! rclone listremotes | grep -q "^${REMOTE_NAME}:$"; then
    echo "❌ rclone remote '${REMOTE_NAME}' is not configured!"
    echo "Run: rclone config"
    exit 1
fi

# 创建输出目录
mkdir -p "${OUTPUT_DIR}"

# 测试连接
echo "🔗 Testing R2 connection..."
if ! rclone lsd "${REMOTE_NAME}:${BUCKET_NAME}" --max-depth 1 > /dev/null 2>&1; then
    echo "❌ Failed to connect to R2 bucket"
    exit 1
fi
echo "✅ Connection successful"
echo ""

# 下载文件
echo "⬇️  Downloading files from R2..."
rclone copy \
    "${REMOTE_NAME}:${BUCKET_NAME}/${PREFIX}" \
    "${OUTPUT_DIR}/${PREFIX}" \
    --progress \
    --transfers 8 \
    --checkers 16 \
    --stats 2s \
    --stats-one-line \
    --s3-no-check-bucket

echo ""
echo "✅ Export completed successfully!"
echo "📁 Files saved to: ${OUTPUT_DIR}/${PREFIX}"
    

使用方法:

bash
12345678910
      chmod +x export-r2-files.sh

# 下载所有 workflow-outputs/ 文件
./export-r2-files.sh

# 下载特定月份的文件
./export-r2-files.sh workflow-outputs/2025-01/

# 指定输出目录
./export-r2-files.sh workflow-outputs/ ./my-exports
    

常见问题

Q1: 遇到 403 Access Denied 错误

原因:API Token 权限不足或配置错误

解决方法

  1. 确认 API Token 有 Object Read 和 Object List 权限
  2. 在 rclone 命令中添加 --s3-no-check-bucket 参数
  3. 或在 rclone config 中添加:no_check_bucket = true

Q2: Endpoint URL 格式不正确

正确格式https://{account_id}.r2.cloudflarestorage.com

错误示例

  • https://{account_id}.r2.cloudflarestorage.com/bucket-name(不要包含存储桶名)
  • https://r2.cloudflarestorage.com(缺少 account_id)

Q3: 如何找到 Account ID?

方法一:从 Cloudflare Dashboard URL 获取

  • 登录后 URL 格式:https://dash.cloudflare.com/{account_id}/...

方法二:从 R2 页面查看

  • 进入 R2 管理页面,查看 Endpoint URL

Q4: rclone 速度慢怎么办?

尝试调整并行参数:

bash
1234
      rclone copy r2prod:bucket/path/ ./local \
  --transfers 16 \      # 增加并行传输数
  --checkers 32 \       # 增加并行检查数
  --buffer-size 128M    # 增加缓冲区大小
    

Q5: 如何只下载特定文件类型?

使用 --include--exclude 参数:

bash
12345678
      # 只下载 .json 文件
rclone copy r2prod:bucket/ ./local --include "*.json"

# 排除 .tmp 文件
rclone copy r2prod:bucket/ ./local --exclude "*.tmp"

# 只下载图片
rclone copy r2prod:bucket/ ./local --include "*.{jpg,png,gif}"
    

其他可选方案

1. AWS CLI

R2 兼容 S3 API,也可以使用 AWS CLI:

bash
123456789101112
      # 配置
aws configure --profile r2
# AWS Access Key ID: [R2 Access Key]
# AWS Secret Access Key: [R2 Secret Key]
# Default region name: auto
# Default output format: json

# 设置 endpoint
export AWS_ENDPOINT_URL=https://{account_id}.r2.cloudflarestorage.com

# 下载文件
aws s3 cp s3://bucket-name/path/ ./local-path/ --recursive --profile r2
    

2. S3-compatible GUI 工具

3. 编程方式

使用 AWS SDK 访问 R2(以 Node.js 为例):

javascript
123456789101112131415161718192021222324252627
      import { S3Client, ListObjectsV2Command, GetObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({
  region: 'auto',
  endpoint: 'https://{account_id}.r2.cloudflarestorage.com',
  credentials: {
    accessKeyId: 'your-access-key',
    secretAccessKey: 'your-secret-key',
  },
});

// 列出对象
const listCommand = new ListObjectsV2Command({
  Bucket: 'bucket-name',
  Prefix: 'workflow-outputs/',
});
const { Contents } = await s3.send(listCommand);

// 下载文件
for (const object of Contents) {
  const getCommand = new GetObjectCommand({
    Bucket: 'bucket-name',
    Key: object.Key,
  });
  const response = await s3.send(getCommand);
  // 处理 response.Body
}
    

总结

  • 推荐方案:rclone(官方推荐,稳定可靠)
  • 备选方案:AWS CLI、GUI 工具、编程 SDK
  • 不推荐:wrangler CLI(不支持批量操作)

参考资料