108

Javaを使用して、特定のバケットにキーが存在するかどうかを確認したいと思います。APIを見ましたが、便利なメソッドはありません。使用しようとしましgetObjectたが、例外が発生しました。

4

16 に答える 16

332

公式JavaAPIにdoesObjectExistメソッドが追加されました。

楽しみ!

于 2016-04-15T17:06:45.537 に答える
60

アップデート:

それをチェックするための新しいAPIがあるようです。このページの別の回答を参照してください:https ://stackoverflow.com/a/36653034/435605

元の投稿:

使用するerrorCode.equals("NoSuchKey")

try {
    AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
    String bucketName = getBucketName();
    s3.createBucket(bucketName);
    S3Object object = s3.getObject(bucketName, getKey());
} catch (AmazonServiceException e) {
    String errorCode = e.getErrorCode();
    if (!errorCode.equals("NoSuchKey")) {
        throw e;
    }
    Logger.getLogger(getClass()).debug("No such key!!!", e);
}

例外についての注意:例外はフロー制御に使用されるべきではないことを私は知っています。問題は、AmazonがこのフローをチェックするためのAPIを提供していなかったことです。例外に関するドキュメントだけです。

于 2013-04-04T09:46:10.100 に答える
25

AWS SDKを使用するには、getObjectMetadataメソッドを使用します。キーが存在しない場合、メソッドはAmazonServiceExceptionをスローします。

private AmazonS3 s3;
...
public boolean exists(String path, String name) {
    try {
        s3.getObjectMetadata(bucket, getS3Path(path) + name); 
    } catch(AmazonServiceException e) {
        return false;
    }
    return true;
}
于 2013-01-29T16:03:38.627 に答える
19

Amazon Java SDK 1.10以降でgetStatusCode()は、HTTP応答のステータスコードを取得するために使用できます。オブジェクトが存在しない場合は404になります。

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import org.apache.http.HttpStatus;

try {
    AmazonS3 s3 = new AmazonS3Client();
    ObjectMetadata object = s3.getObjectMetadata("my-bucket", "my-client");
} catch (AmazonS3Exception e) {
    if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
        // bucket/key does not exist 
    } else {
        throw e;
    }
}

getObjectMetadata()消費するリソースが少なく、のように応答を閉じる必要はありませんgetObject()


以前のバージョンではgetErrorCode()、適切な文字列を使用して確認できます(バージョンによって異なります)。

于 2015-08-04T17:50:05.023 に答える
19

SDK V2で実際にオブジェクトを取得するという過負荷なしにそれを行う正しい方法は、S3Client.headObjectを使用することです。AWS変更ログによって公式に裏付けられています。

コード例:

public boolean exists(String bucket, String key) {
    try {
        HeadObjectResponse headResponse = client
                .headObject(HeadObjectRequest.builder().bucket(bucket).key(key).build());
        return true;
    } catch (NoSuchKeyException e) {
        return false;
    }
}
于 2019-05-08T10:14:51.037 に答える
5

ListObjectsRequest設定プレフィックスをキーとして使用します。

.NETコード:

 public bool Exists(string key)
    {

        using (Amazon.S3.AmazonS3Client client = (Amazon.S3.AmazonS3Client)Amazon.AWSClientFactory.CreateAmazonS3Client(m_accessKey, m_accessSecret))
        {
            ListObjectsRequest request = new ListObjectsRequest();
            request.BucketName = m_bucketName;
            request.Prefix = key;
            using (ListObjectsResponse response = client.ListObjects(request))
            {

                foreach (S3Object o in response.S3Objects)
                {
                    if( o.Key == key )
                        return true;
                }
                return false;
            }
        }
    }.
于 2013-05-16T14:05:23.993 に答える
5

PHPの場合(質問はJavaですが、Googleが私をここに連れてきました)、ストリームラッパーとfile_existsを使用できます

$bucket = "MyBucket";
$key = "MyKey";
$s3 = Aws\S3\S3Client->factory([...]);
$s3->registerStreamWrapper();
$keyExists = file_exists("s3://$bucket/$key");
于 2014-07-16T21:00:50.953 に答える
4

このJavaコードは、キー(ファイル)がs3バケットに存在するかどうかを確認します。

public static boolean isExistS3(String accessKey, String secretKey, String bucketName, String file) {

    // Amazon-s3 credentials
    AWSCredentials myCredentials = new BasicAWSCredentials(accessKey, secretKey); 
    AmazonS3Client s3Client = new AmazonS3Client(myCredentials); 

    ObjectListing objects = s3Client.listObjects(new ListObjectsRequest().withBucketName(bucketName).withPrefix(file));

    for (S3ObjectSummary objectSummary: objects.getObjectSummaries()) {
        if (objectSummary.getKey().equals(file)) {
            return true;
        }
    }
    return false;
}
于 2013-05-23T15:55:50.130 に答える
3

パスをバケットとオブジェクトに分割します。メソッドを使用してバケットをdoesBucketExistテストし、リストのサイズを使用してオブジェクトをテストします(存在しない場合は0)。したがって、このコードは次のようになります。

String bucket = ...;
String objectInBucket = ...;
AmazonS3 s3 = new AmazonS3Client(...);
return s3.doesBucketExist(bucket) 
       && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
于 2015-12-17T20:01:34.317 に答える
3

他の答えはAWSSDKv1用です。AWS SDK v2(現在は2.3.9)のメソッドは次のとおりです。

getObjectMetadataおよびdoesObjectExistメソッドは現在v2SDKに含まれていないことに注意してください。したがって、それらはもはやオプションではありません。またはのいずれgetObjectかを使用する必要がありlistObjectsます。

listObjects現在、通話料金は。より12.5倍高くなっていgetObjectます。ただし、AWSはダウンロードされたデータに対しても課金するためgetObject 、ファイルが存在する場合の料金が高くなります。ファイルが存在する可能性が非常に低い限り(たとえば、新しいUUIDキーをランダムに生成し、それが取得されていないことを再確認する必要がある場合)、getObject私の計算では呼び出しが大幅に安くなります。

念のため、range()AWSにファイルの数バイトのみを送信するように要求する仕様を追加しました。私の知る限り、SDKは常にこれを尊重し、ファイル全体のダウンロードに対して料金を請求することはありません。しかし、私はそれを確認していませんので、あなた自身の責任でその行動に依存してください!range(また、 S3オブジェクトの長さが0バイトの場合の動作もわかりません。)

    private boolean sanityCheckNewS3Key(String bucket, String key) {

        ResponseInputStream<GetObjectResponse> resp = null;
        try {
            resp = s3client.getObject(GetObjectRequest.builder()
                .bucket(bucket)
                .key(key)
                .range("bytes=0-3")
                .build());
        }
        catch (NoSuchKeyException e) {
            return false;
        }
        catch (AwsServiceException se) {
            throw se;
        }
        finally {
            if (resp != null) {
                try {
                    resp.close();
                } catch (IOException e) {
                    log.warn("Exception while attempting to close S3 input stream", e);
                }
            }
        }
        return true;
    }
}

注:このコードは、他の場所で宣言および初期化されていることを前提s3Clientとしています。logメソッドはブール値を返しますが、例外をスローする可能性があります。

于 2019-02-02T00:47:16.573 に答える
2

オブジェクトの使用。指定されたキーがAWSS3に存在するかどうかを確認するJava関数。

boolean isExist(String key)
    {
        ObjectListing objects = amazonS3.listObjects(new ListObjectsRequest().withBucketName(bucketName).withPrefix(key));

        for (S3ObjectSummary objectSummary : objects.getObjectSummaries())
        {
            if (objectSummary.getKey().equals(key))
            {
                return true;
            }

        }
        return false;
    }
于 2015-12-24T05:35:47.833 に答える
2

他の人が述べているように、AWS S3 Java SDK 2.10以降では、HeadObjectRequestオブジェクトを使用して、S3バケットにファイルがあるかどうかを確認できます。これは、実際にファイルを取得することなく、GETリクエストのように機能します。

他の人が実際に上記のコードを追加していないため、サンプルコード:

public boolean existsOnS3 () throws Exception {
    try {
       S3Client s3Client = S3Client.builder ().credentialsProvider (...).build ();
       HeadObjectRequest headObjectRequest = HeadObjectRequest.builder ().bucket ("my-bucket").key ("key/to/file/house.pdf").build ();
       HeadObjectResponse headObjectResponse = s3Client.headObject (headObjectRequest);
       return headObjectResponse.sdkHttpResponse ().isSuccessful ();    
   }
   catch (NoSuchKeyException e) {
      //Log exception for debugging
      return false;
   }
}
于 2020-02-25T14:38:41.993 に答える
1

jetS3t APIのisObjectInBucket()メソッドを使用してこれを行う簡単な方法があります。

サンプルコード:

ProviderCredentials awsCredentials = new AWSCredentials(
                awsaccessKey,
                awsSecretAcessKey);

        // REST implementation of S3Service
        RestS3Service restService = new RestS3Service(awsCredentials);

        // check whether file exists in bucket
        if (restService.isObjectInBucket(bucket, objectKey)) {

            //your logic

        }
于 2015-05-28T04:14:10.563 に答える
1

私が使用したときにもこの問題に直面しました

String BaseFolder = "3patti_Logs"; 
S3Object object = s3client.getObject(bucketName, BaseFolder);
 

エラーキーが見つかりません

叩いて試してみると

String BaseFolder = "3patti_Logs"; 
S3Object object = s3client.getObject(bucketName, BaseFolder+"/");

動作しました。このコードは1.9jarで動作します。それ以外の場合は、1.11に更新し、上記のようにdoesObjectExistを使用します。

于 2020-07-16T06:51:07.697 に答える
0

jets3tライブラリを使用します。AWSSDKよりもはるかに簡単で堅牢です。このライブラリを使用して、s3service.getObjectDetails()を呼び出すことができます。これにより、オブジェクトの詳細(コンテンツではなく)のみがチェックおよび取得されます。オブジェクトが欠落している場合は404をスローします。したがって、その例外をキャッチして、アプリで処理できます。

ただし、これを機能させるには、そのバケットのユーザーがListBucketにアクセスできる必要があります。GetObjectアクセスだけでは機能しません。その理由は、ListBucketにアクセスできない場合、Amazonはキーの存在を確認できないようにするためです。キーが存在するかどうかを知るだけで、悪意のあるユーザーにとっても十分な場合があります。したがって、ListBucketにアクセスできない限り、アクセスすることはできません。

于 2011-11-29T01:28:20.313 に答える
-1

または、 Minio-Javaクライアントライブラリとそのオープンソースを使用して、 AWSS3APIと互換性を持たせることもできます。

Minio-JavaStatObject.javaの例を同じように使用できます。

import io.minio.MinioClient;
import io.minio.errors.MinioException;

import java.io.InputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;

import org.xmlpull.v1.XmlPullParserException;


public class GetObject {
  public static void main(String[] args)
    throws NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException, MinioException {
    // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
    // dummy values, please replace them with original values.
    // Set s3 endpoint, region is calculated automatically
    MinioClient s3Client = new MinioClient("https://s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY");
    InputStream stream = s3Client.getObject("my-bucketname", "my-objectname");

    byte[] buf = new byte[16384];
    int bytesRead;
    while ((bytesRead = stream.read(buf, 0, buf.length)) >= 0) {
      System.out.println(new String(buf, 0, bytesRead));
    }

    stream.close();
  }
}

お役に立てば幸いです。

免責事項:私はMinioで働いています

于 2016-05-13T14:39:09.320 に答える