使用API从Amazon S3删除文件夹

15

我正在尝试删除一个文件夹内的所有文件,该文件夹基本上是日期。

例如,如果文件夹“08-10-2015”下有100个文件,我希望发送文件夹名称而不是这100个文件名。

我正在尝试以下代码,但它对我没有起作用。

        DeleteObjectsRequest multiObjectDeleteRequest = new DeleteObjectsRequest();

        multiObjectDeleteRequest.BucketName = bucketName;

        multiObjectDeleteRequest.AddKey(keyName + "/" + folderName + "/");


        AmazonS3Config S3Config = new AmazonS3Config()
        {
            ServiceURL = string.Format(servicehost)
        };

        using (IAmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(accesskey, secretkey, S3Config))
        {
            try
            {
                DeleteObjectsResponse response = client.DeleteObjects(multiObjectDeleteRequest);
                Console.WriteLine("Successfully deleted all the {0} items", response.DeletedObjects.Count);

            }
            catch (DeleteObjectsException e)
            {
                // Process exception.
            }

我正在使用上述代码,但它不起作用。


5
S3 API不允许您直接按文件夹删除,因为在S3中文件夹并不存在(它们是向用户呈现的逻辑结构)。相反,您需要在DeleteObjectsRequest中指定多个对象键。您可以通过在ListObjectsRequestPrefix属性中指定“文件夹”的所有键,来搜索特定“文件夹”下的所有键,这样与删除相结合,即可完成您想要的操作。 - wkl
3个回答

23

我认为您可以使用以下代码删除整个文件夹:

 AmazonS3Config cfg = new AmazonS3Config();
 cfg.RegionEndpoint = Amazon.RegionEndpoint.EUCentral1;
 string bucketName = "your bucket name";
 AmazonS3Client s3Client = new AmazonS3Client("your access key", "your secret key", cfg);
 S3DirectoryInfo directoryToDelete = new S3DirectoryInfo(s3Client, bucketName, "your folder name or full folder key");
 directoryToDelete.Delete(true); // true will delete recursively in folder inside

我正在使用 Amazon AWSSDK.Core 和 AWSSDK.S3 版本 3.1.0.0 用于 .net 3.5。希望这能对您有所帮助。


非常好用!谢谢! - forrert
看起来 Go 没有这样的能力 :( - Vitaly Zdanevich
我们是否具备使用 Node JS SDK 的能力? - sekhar
5
似乎.NET核心或标准版本都不支持S3.IO。因此,我放弃了它(否则这将是我的选择,递归删除文件夹会更容易)。 - Veverke
不支持在Core中,但在Full中支持。原因不确定。 - Dzmitry Lahoda

11

你需要:

  1. 列出文件夹中的所有对象
  2. 获取每个对象的键
  3. 将此键添加到多重删除对象请求中
  4. 发出请求以删除所有对象

 AmazonS3Config S3Config = new AmazonS3Config()
    {
        ServiceURL = "s3.amazonaws.com",
        CommunicationProtocol = Amazon.S3.Model.Protocol.HTTP,
    };

 const string AWS_ACCESS_KEY = "xxxxxxxxxxxxxxxx";
 const string AWS_SECRET_KEY = "yyyyyyyyyyyyyyyy";            
 AmazonS3Client client = new AmazonS3Client(AWS_ACCESS_KEY, AWS_SECRET_KEY, S3Config);

    DeleteObjectsRequest request2 = new DeleteObjectsRequest();
    ListObjectsRequest request = new ListObjectsRequest
    {
        BucketName = "yourbucketname",
        Prefix = "yourprefix"

    };

    ListObjectsResponse response = await client.ListObjectsAsync(request);
            // Process response.
            foreach (S3Object entry in response.S3Objects)
            {

                request2.AddKey(entry.Key);
            }
    request2.BucketName = "yourbucketname";
    DeleteObjectsResponse response2 = await client.DeleteObjectsAsync(request2);

似乎不起作用。当S3上的文件夹为空时,列出对象将返回零条目。 - david marcus
注意 response.IsTruncated - malat

1

我不确定为什么他们没有在未来的SDK中保留这种方法,但是对于那些感兴趣的人,这里是S3DirectoryInfo.Delete方法的实现:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest
            {
                BucketName = bucket,
                Prefix = directoryPrefix
            };
            
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest
            {
                BucketName = bucket
            };
            
            ListObjectsResponse listObjectsResponse = null;
            do
            {
                listObjectsResponse = s3Client.ListObjects(listObjectsRequest);
                foreach (S3Object item in listObjectsResponse.S3Objects.OrderBy((S3Object x) => x.Key))
                {
                    deleteObjectsRequest.AddKey(item.Key);
                    if (deleteObjectsRequest.Objects.Count == 1000)
                    {
                        s3Client.DeleteObjects(deleteObjectsRequest);
                        deleteObjectsRequest.Objects.Clear();
                    }

                    listObjectsRequest.Marker = item.Key;
                }
            }
            while (listObjectsResponse.IsTruncated);
            if (deleteObjectsRequest.Objects.Count > 0)
            {
                s3Client.DeleteObjects(deleteObjectsRequest);
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接