我有以下工作代码从Amazon s3中删除对象
params := &s3.DeleteObjectInput{
Bucket: aws.String("Bucketname"),
Key : aws.String("ObjectKey"),
}
s3Conn.DeleteObjects(params)
但我想要做的是使用通配符**删除文件夹下的所有文件。我知道亚马逊s3不会将“x / y / file.jpg”视为x中的文件夹y,但我想要实现的是通过提及“x / y *”删除具有相同前缀的所有后续对象。试过amazon multi object delete
params := &s3.DeleteObjectsInput{
Bucket: aws.String("BucketName"),
Delete: &s3.Delete{
Objects: []*s3.ObjectIdentifier {
{
Key : aws.String("x/y/.*"),
},
},
},
}
result , err := s3Conn.DeleteObjects(params)
我知道在php中可以通过 s3-> delete_all_objects 轻松完成this answer。在GOlang中可以采取相同的行动。
答案 0 :(得分:3)
不幸的是goamz包没有类似于PHP库delete_all_objects
的方法。
但是,此处提供了PHP delete_all_objects
的源代码(切换源视图):http://docs.aws.amazon.com/AWSSDKforPHP/latest/#m=AmazonS3/delete_all_objects
以下是重要的代码行:
public function delete_all_objects($bucket, $pcre = self::PCRE_ALL)
{
// Collect all matches
$list = $this->get_object_list($bucket, array('pcre' => $pcre));
// As long as we have at least one match...
if (count($list) > 0)
{
$objects = array();
foreach ($list as $object)
{
$objects[] = array('key' => $object);
}
$batch = new CFBatchRequest();
$batch->use_credentials($this->credentials);
foreach (array_chunk($objects, 1000) as $object_set)
{
$this->batch($batch)->delete_objects($bucket, array(
'objects' => $object_set
));
}
$responses = $this->batch($batch)->send();
正如您所看到的,PHP代码实际上会在存储桶上发出HTTP请求,以首先获取与PCRE_ALL
匹配的所有文件,const PCRE_ALL = '/.*/i';
定义为delete_all_objects
。
您一次只能删除1000个文件,因此Nov 19, 2015 9:07:50 PM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/SoccerSpringMaven3/springSoccer/users] in DispatcherServlet with name 'springSoccer'
会创建一个批处理功能,一次删除1000个文件。
您必须在go程序中创建相同的功能,因为goamz包还不支持此功能。幸运的是,它应该只有几行代码,并且您有PHP库的指南。
一旦完成,可能值得提交goamz包的拉取请求!
答案 1 :(得分:1)
您可以使用mc工具:
mc rm -r --force https://BucketName.s3.amazonaws.com/x/y
它将删除前缀为" x / y"
的所有对象你可以使用minio-go像这样使用Go实现相同的目标:
package main
import (
"log"
"github.com/minio/minio-go"
)
func main() {
config := minio.Config{
AccessKeyID: "YOUR-ACCESS-KEY-HERE",
SecretAccessKey: "YOUR-PASSWORD-HERE",
Endpoint: "https://s3.amazonaws.com",
}
// find Your S3 endpoint here http://docs.aws.amazon.com/general/latest/gr/rande.html
s3Client, err := minio.New(config)
if err != nil {
log.Fatalln(err)
}
isRecursive := true
for object := range s3Client.ListObjects("BucketName", "x/y", isRecursive) {
if object.Err != nil {
log.Fatalln(object.Err)
}
err := s3Client.RemoveObject("BucketName", object.Key)
if err != nil {
log.Fatalln(err)
continue
}
log.Println("Removed : " + object.Key)
}
}
答案 2 :(得分:0)
在游戏中有些晚,但是由于遇到同样的问题,我创建了一个小的pkg,您可以将其复制到代码库并根据需要导入。
func ListKeysInPrefix(s s3iface.S3API, bucket, prefix string) ([]string, error) {
res, err := s.Client.ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
Prefix: aws.String(prefix),
})
if err != nil {
return []string{}, err
}
var keys []string
for _, key := range res.Contents {
keys = append(keys, *key.Key)
}
return keys, nil
}
func createDeleteObjectsInput(keys []string) *s3.Delete {
rm := []*s3.ObjectIdentifier{}
for _, key := range keys {
rm = append(rm, &s3.ObjectIdentifier{Key: aws.String(key)})
}
return &s3.Delete{Objects: rm, Quiet: aws.Bool(false)}
}
func DeletePrefix(s s3iface.S3API, bucket, prefix string) error {
keys, err := s.ListKeysInPrefix(bucket, prefix)
if err != nil {
panic(err)
}
_, err = s.Client.DeleteObjects(&s3.DeleteObjectsInput{
Bucket: aws.String(bucket),
Delete: s.createDeleteObjectsInput(keys),
})
if err != nil {
return err
}
return nil
}
因此,如果您有一个名为“ somebucket”的存储桶,其结构如下:s3://somebucket/foo/some-prefixed-folder/bar/test.txt
,并且想从some-prefixed-folder
开始删除,用法将是:
func main() {
// create your s3 client here
// client := ....
err := DeletePrefix(client, "somebucket", "some-prefixed-folder")
if err != nil {
panic(err)
}
}
此实现仅允许从ListObjectsV2
实现的给定前缀中删除最多1000个条目-但它是分页的,因此需要添加功能以保持刷新结果直到结果<1000。 / p>