如何在S3公共中制作10,000个文件

时间:2010-06-29 15:49:54

标签: amazon-s3 amazon-web-services

我在一个包含10,000个文件的文件夹中有一个文件夹。似乎没有办法上传它们并立即公开。所以我上传了所有内容,它们都是私密的,我需要将它们全部公开。

我已经尝试过aws控制台,它只是出错(适用于文件较少的文件夹)。

我尝试在Firefox中使用S3组织,同样的事情。

是否有一些软件或某些脚本可以让所有这些公开?

10 个答案:

答案 0 :(得分:108)

您可以生成一个存储桶策略(请参阅下面的示例),该策略可以访问存储桶中的所有文件。可以通过AWS控制台将存储桶策略添加到存储桶中。

{
    "Id": "...",
    "Statement": [ {
        "Sid": "...",
        "Action": [
            "s3:GetObject"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::bucket/*",
        "Principal": {
            "AWS": [ "*" ]
        }
    } ]
}

另请参阅亚马逊提供的以下政策生成工具。

http://awspolicygen.s3.amazonaws.com/policygen.html

答案 1 :(得分:53)

如果您是第一次上传,可以在命令行上将文件设置为公开:

aws s3 sync . s3://my-bucket/path --acl public-read

Using High-Level s3 Commands with the AWS Command Line Interface

中所述

不幸的是,它仅在上传文件时应用ACL。它(在我的测试中)没有将ACL应用于已经上传的文件。

如果您确实想要更新现有对象,您曾经能够将存储桶同步到自身,但这似乎已停止工作。

[不再工作]这可以从命令行完成:

aws s3 sync s3://my-bucket/path s3://my-bucket/path --acl public-read

(所以这不再回答这个问题,而是留下答案以供参考。)

答案 2 :(得分:32)

我不得不改变几十万件物品。我启动了一个EC2实例来运行它,这使得它变得更快。您需要先安装aws-sdk gem。

以下是代码:

require 'rubygems'
require 'aws-sdk'


# Change this stuff.
AWS.config({
    :access_key_id => 'YOURS_HERE',
    :secret_access_key => 'YOURS_HERE',
})
bucket_name = 'YOUR_BUCKET_NAME'


s3 = AWS::S3.new()
bucket = s3.buckets[bucket_name]
bucket.objects.each do |object|
    puts object.key
    object.acl = :public_read
end

答案 3 :(得分:22)

我有同样的问题,@DanielVonFange的解决方案已经过时,因为SDK的新版本已经发布。

使用AWS Ruby SDK添加适合我的代码段:

require 'aws-sdk'

Aws.config.update({
  region: 'REGION_CODE_HERE',
  credentials: Aws::Credentials.new(
    'ACCESS_KEY_ID_HERE',
    'SECRET_ACCESS_KEY_HERE'
  )
})
bucket_name = 'BUCKET_NAME_HERE'

s3 = Aws::S3::Resource.new
s3.bucket(bucket_name).objects.each do |object|
  puts object.key
  object.acl.put({ acl: 'public-read' })
end

答案 4 :(得分:14)

只是想在新的S3控制台中添加它,您可以选择文件夹并选择Make public以使文件夹中的所有文件都公开。它作为后台任务,因此它应该处理任意数量的文件。

Make Public

答案 5 :(得分:3)

使用cli:

aws s3 ls s3://bucket-name --recursive > all_files.txt && grep .jpg all_files.txt > files.txt && cat files.txt | awk '{cmd="aws s3api put-object-acl --acl public-read --bucket bucket-name --key "$4;system(cmd)}'

答案 6 :(得分:2)

查看BucketExplorer它可以很好地管理批量操作,并且是一个可靠的S3客户端。

答案 7 :(得分:2)

如果这需要我自己,但文件的数量使得它可以在串行中减速。所以我在a scriptiron.io服务上写了IronWorker。他们每月500个免费计算小时数足以处理大型存储桶(如果超过这个数量,那么定价是合理的)。由于它是并行完成的,所以我在不到一分钟的时间内完成了32,000个物体。另外我相信他们的服务器在EC2上运行,因此作业和S3之间的通信很快。

欢迎任何人根据自己的需要使用我的脚本。

答案 8 :(得分:0)

你会认为他们会公开阅读默认行为,不是吗? :) 我在构建自定义API以与C#解决方案中的S3接口时分享了您的挫败感。以下是完成上传S3对象并默认将其设置为公共读取访问的片段:

public void Put(string bucketName, string id, byte[] bytes, string contentType, S3ACLType acl) {
     string uri = String.Format("https://{0}/{1}", BASE_SERVICE_URL, bucketName.ToLower());
     DreamMessage msg = DreamMessage.Ok(MimeType.BINARY, bytes);
     msg.Headers[DreamHeaders.CONTENT_TYPE] = contentType;
     msg.Headers[DreamHeaders.EXPECT] = "100-continue";
     msg.Headers[AWS_ACL_HEADER] = ToACLString(acl);
     try {
        Plug s3Client = Plug.New(uri).WithPreHandler(S3AuthenticationHeader);
        s3Client.At(id).Put(msg);
     } catch (Exception ex) {
        throw new ApplicationException(String.Format("S3 upload error: {0}", ex.Message));
     }
}

ToACLString(acl)函数返回 public-read ,BASE_SERVICE_URL为 s3.amazonaws.com ,AWS_ACL_HEADER常量为 x-amz-acl 。插件和DreamMessage的东西可能看起来很奇怪,因为我们正在使用Dream框架来简化我们的http通信。基本上我们使用指定的头文件和每个aws规范的特殊头部签名进行http PUT(有关如何构造授权头的示例,请参阅aws docs中的此页面。)

要更改现有的1000个对象ACL,您可以编写脚本,但使用GUI工具修复即时问题可能更容易。到目前为止,我所使用的最好的是来自一家名为cloudberry的公司,用于S3;看起来他们至少有一个产品可以免费试用15天。我刚刚验证它将允许您一次选择多个对象并通过上下文菜单将其ACL设置为公共。享受云!

答案 9 :(得分:0)

如果您的文件名有空格,我们可以采用上面 Alexander Vitanov 的回答并通过 jq 运行它:

#!/bin/bash
# make every file public in a bucket example
bucket=www.example.com
IFS=$'\n' && for tricky_file in $(aws s3api list-objects --bucket "${bucket}" | jq -r '.Contents[].Key')
do
  echo $tricky_file
  aws s3api put-object-acl --acl public-read --bucket "${bucket}" --key "$tricky_file"
done