簡體   English   中英

刪除 amazon s3 中的文件、目錄和桶 java

[英]Delete files, directories and buckets in amazon s3 java

我想知道如何做到這一點。 我查看了 sdk 文檔並提供了一些示例,但我對語法的一般情況感到困惑。

如果我想刪除一個文件,我假設我使用deleteObject(path, key) 然而,“關鍵”是什么?

還有你如何刪除一個目錄? 我似乎找不到這樣做的方法。

這段代碼對我有用。 folderPath就像“topDir / secondDir /”

void deleteObjectsInFolder(String bucketName, String folderPath) {
   for (S3ObjectSummary file : s3.listObjects(bucketName, folderPath).getObjectSummaries()){
      s3.deleteObject(bucketName, file.getKey());
    }
}

S3中的“鍵”類似於文件路徑:

http://bucket.s3.amazonaws.com/some/path/to/use

...位於一個名為bucket的存儲bucket並且具有some/path/to/use

它實際上並不是一條路徑,因為沒有文件夾。 S3密鑰只是一個大目錄(整個存儲桶)中文件的文件名。 S3鍵可以包含/ ,但除非您使用列出存儲桶設置delimiter參數,否則它沒有特殊含義。

換句話說,具有對象命名的some/object不告訴你對象的任何some (可能或可能不存在-兩個對象都沒有關系)。

但是,你可以請求具有特定前綴的密鑰,所以我可以說“給我所有的密鑰以some/path/to/開頭,它將返回some/path/to/use 。它看起來像”列出一個目錄“,但是它實際上只是要求以特定字符串開頭的文件。

我可以很容易地命名這樣的事情:

somepathtousea
somepathtouseb

並且說“給我一切從一些somepathtouse開始”(並且它會說somepathtouseasomepathtouseb )。

注意:S3 URL 有多種形式

 http://s3.amazonaws.com/bucket/key http://bucket.s3.amazonaws.com/key http://bucket/key (where bucket is a DNS CNAME record pointing to bucket.s3.amazonaws.com) 

編輯:

我查看了JavaDocs ,這是我看到的函數簽名(對於AmazonS3Client ):

public void deleteObject(java.lang.String bucketName,
                         java.lang.String key)
                  throws AmazonClientException,
                         AmazonServiceException

再次編輯:

文件夾現在可以存在,作為零長度對象,具有內容類型的application/x-directory和以/結尾的鍵:

$ AWS_PROFILE=prod aws s3api head-object --bucket example-bucket --key example-directory/
{
    "AcceptRanges": "bytes",
    "LastModified": "Mon, 29 Apr 2019 14:59:36 GMT",
    "ContentLength": 0,
    "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
    "ContentType": "application/x-directory",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

這仍然只是慣例,並沒有什么能阻止你讓文件結束/或“文件夾”里面的文件不存在。

您可能需要查看此示例 ,以快速參考如何從S3中刪除對象。

delete的語法實際上是deleteObject( bucketName, key ) ,其中bucketName是放置文件的存儲桶,key是要在存儲桶中刪除的文件的名稱。

可以將存儲桶視為硬盤驅動器,如C:\\,D:\\等。並將鍵作為要刪除的文件的絕對路徑名。

/ *這是適用於我的解決方案。 這里Bucket_Name是我在S3上的桶名,key是Bucket_Name下的路徑。 所以,如果S3上的絕對路徑是:

S3:// MY_BUCKET /路徑/要/我的/文件夾

那么,下面的代碼應該工作。 * /


    String Bucket_Name = "my_bucket";
    String key = "Path/to/my/folder";   
    ObjectListing objects = s3Client.listObjects(BUCKET_NAME, key);
        for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) 
            {
            s3Client.deleteObject(BUCKET_NAME, objectSummary.getKey());
            }           

適合我,謹防截斷!

    long start = System.currentTimeMillis();
    long totalSize = 0;
    int totalItems = 0;

    String key ="path/to/folder/"
    String bucket = "my-bucket"

    final ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix(key);

    ObjectListing objects = s3.listObjects(listObjectsRequest);
    do {
        for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) {
            totalSize += objectSummary.getSize();
            totalItems++;
            s3.deleteObject(bucketName, objectSummary.getKey());
        }
        objects = s3.listNextBatchOfObjects(objects);
    } while (objects.isTruncated());

    long stop = System.currentTimeMillis();

    LOG.trace("User {} had {} items with {} Kb, took {} ms to delete", user.getName(), totalItems, totalSize / 1024, stop
            - start);

ListObjectsV2Result為我工作。 試試一次。

private void deleteObjectsInFolder() {
    try {
        ListObjectsV2Result result;
        do {
            String folderPath =   " ";



            result = s3.listObjectsV2(Constants.BUCKET_NAME, folderPath);

            Log.e("count:", result.getKeyCount() + "");

            if (result.getKeyCount() != 0) {

                for (S3ObjectSummary objectSummary :
                        result.getObjectSummaries()) {
                    s3.deleteObject(Constants.BUCKET_NAME, objectSummary.getKey());
                }

            }


            System.out.println("Next Continuation Token : " + result.getNextContinuationToken());
        } while (result.isTruncated() == true);

    } catch (AmazonServiceException ase) {
        System.out.println("Caught an AmazonServiceException, " +
                "which means your request made it " +
                "to Amazon S3, but was rejected with an error response " +
                "for some reason.");
        System.out.println("Error Message:    " + ase.getMessage());
        System.out.println("HTTP Status Code: " + ase.getStatusCode());
        System.out.println("AWS Error Code:   " + ase.getErrorCode());
        System.out.println("Error Type:       " + ase.getErrorType());
        System.out.println("Request ID:       " + ase.getRequestId());
    } catch (AmazonClientException ace) {
        System.out.println("Caught an AmazonClientException, " +
                "which means the client encountered " +
                "an internal error while trying to communicate" +
                " with S3, " +
                "such as not being able to access the network.");
        System.out.println("Error Message: " + ace.getMessage());
    }
}

由於問題是在亞馬遜S3 java中要求刪除文件,目錄和存儲桶,我想提供刪除非空S3存儲桶的代碼( AWS參考 ):

 public void deleteBucket(final String bucketName) {

        final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();

        try {
            ObjectListing objectListing = s3.listObjects(bucketName);
            while (true) {
                for (Iterator<?> iterator = objectListing.getObjectSummaries().iterator(); iterator.hasNext(); ) {
                    S3ObjectSummary summary = (S3ObjectSummary) iterator.next();
                    s3.deleteObject(bucketName, summary.getKey());
                }

                if (objectListing.isTruncated()) {
                    objectListing = s3.listNextBatchOfObjects(objectListing);
                } else {
                    break;
                }
            }

            VersionListing versionListing = s3.listVersions(new ListVersionsRequest().withBucketName(bucketName));
            while (true) {
                for (Iterator<?> iterator = versionListing.getVersionSummaries().iterator(); iterator.hasNext(); ) {
                    S3VersionSummary vs = (S3VersionSummary) iterator.next();
                    s3.deleteVersion(bucketName, vs.getKey(), vs.getVersionId());
                }

                if (versionListing.isTruncated()) {
                    versionListing = s3.listNextBatchOfVersions(versionListing);
                } else {
                    break;
                }
            }

            s3.deleteBucket(bucketName);
        } catch (AmazonServiceException e) {
            System.err.println(e.getErrorMessage());
        }
    }

通過批量刪除S3存儲桶中的對象列表:

public void deleteObjects(String bucketName, List<String> keys) {

    List<KeyVersion> bulk = new ArrayList<>();
    for (int i = 0; i < keys.size(); i++) {
        bulk.add(new KeyVersion(keys.get(i)));
        if (i % 100 == 0) {
            try {
                s3Client.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(bulk));
            } catch (Exception e) {
                System.err.println(e.getErrorMessage());
            }
            bulk.clear();
        }
    }
    if (bulk.size() > 0) {
        try {
            s3Client.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(bulk));
        } catch (Exception e) {
            System.err.println(e.getErrorMessage());
        }
    }
}

資料來源: http//codeflex.co/delete-objects-from-amazon-s3-bucket-using-aws-sdk-for-java/

這行代碼適用於我的情況,其中keyName是文件名:

s3Client.deleteObject(new DeleteObjectRequest(bucketName, keyName));

您可以嘗試以下方法,即使是截斷的頁面,它也會處理刪除,並且它將遞歸刪除給定目錄中的所有內容:

   public Set<String> listS3DirFiles(String bucket, String dirPrefix) {
        ListObjectsV2Request s3FileReq = new ListObjectsV2Request()
                .withBucketName(bucket)
                .withPrefix(dirPrefix)
                .withDelimiter("/");

        Set<String> filesList = new HashSet<>();
        ListObjectsV2Result objectsListing;
        try {
            do {
                objectsListing = amazonS3.listObjectsV2(s3FileReq);
                objectsListing.getCommonPrefixes().forEach(folderPrefix -> {
                    filesList.add(folderPrefix);
                    Set<String> tempPrefix = listS3DirFiles(bucket, folderPrefix);
                    filesList.addAll(tempPrefix);
                });

                for (S3ObjectSummary summary: objectsListing.getObjectSummaries()) {
                    filesList.add(summary.getKey());
                }

                s3FileReq.setContinuationToken(objectsListing.getNextContinuationToken());
            } while(objectsListing.isTruncated());
        } catch (SdkClientException e) {
            System.out.println(e.getMessage());
            throw e;
        }

        return filesList;
    }

    public boolean deleteDirectoryContents(String bucket, String directoryPrefix) {
        Set<String> keysSet = listS3DirFiles(bucket, directoryPrefix);

        if (keysSet.isEmpty()) {
            System.out.println("Given directory {} doesn't have any file "+ directoryPrefix);
            return false;
        }

        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket)
                .withKeys(keysSet.toArray(new String[0]));
        try {
            amazonS3.deleteObjects(deleteObjectsRequest);
        }  catch (SdkClientException e) {
            System.out.println(e.getMessage());
            throw e;
        }

        return true;
    }

kotlin

class S3(
    var bucketName: String? = null,
    var key: String? = null,
    val accessKey: String? = null,
    val secretKey: String? = null,
    val region: String? = null
)

fun delete(
    s3: S3,
    keyword: String = "",
) {
    with(s3) {
        val client = client(accessKey, secretKey, region)

        var objects = client.listObjects(bucketName, key)
        while (true) {
            for (i in objects.objectSummaries) {
                if (!i.key.contains(keyword)) {
                    continue
                }
                client.deleteObject(bucketName, i.key)
            }

            if (objects.isTruncated) {
                objects = client.listNextBatchOfObjects(objects)
            } else {
                break
            }
        }

        var versions = client.listVersions(bucketName, key)
        while (true) {
            for (i in versions.versionSummaries) {
                if (!i.key.contains(keyword)) {
                    continue
                }
                client.deleteVersion(bucketName, i.key, i.versionId)
            }

            if (versions.isTruncated) {
                versions = client.listNextBatchOfVersions(versions)
            } else {
                break
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM