Saya ingin memeriksa apakah ada kunci dalam bucket tertentu menggunakan Java. Saya melihat API tetapi tidak ada metode yang berguna. Saya mencoba menggunakan getObject
tetapi itu membuat pengecualian.
java
amazon-web-services
amazon-s3
aws-sdk
di Langkah-Nya
sumber
sumber
Jawaban:
Gunakan perpustakaan jets3t. Ini jauh lebih mudah dan kuat daripada sdk AWS. Menggunakan pustaka ini, Anda bisa memanggil, s3service.getObjectDetails (). Ini akan memeriksa dan mengambil hanya detail objek (bukan konten) objek. Ini akan melempar 404 jika objeknya hilang. Jadi Anda bisa menangkap pengecualian itu dan menanganinya di aplikasi Anda.
Tetapi agar ini berfungsi, Anda harus memiliki akses ListBucket untuk pengguna di keranjang itu. Akses GetObject saja tidak akan bekerja. Alasannya, Amazon akan mencegah Anda memeriksa keberadaan kunci jika Anda tidak memiliki akses ListBucket. Hanya mengetahui apakah kunci ada atau tidak, juga akan cukup untuk pengguna jahat dalam beberapa kasus. Karenanya, kecuali mereka memiliki akses ListBucket, mereka tidak akan dapat melakukannya.
sumber
Sekarang ada metode doesObjectExist di API Java resmi.
Nikmati!
sumber
doesObjectExist
dari 2.x SDK (saat ini v2.3.9).Memperbarui:
Sepertinya ada API baru untuk memeriksa hal itu. Lihat jawaban lain di halaman ini: https://stackoverflow.com/a/36653034/435605
Posting asli:
Menggunakan
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); }
Catatan tentang pengecualian: Saya tahu pengecualian tidak boleh digunakan untuk kontrol aliran. Masalahnya adalah Amazon tidak menyediakan api apa pun untuk memeriksa aliran ini - hanya dokumentasi tentang pengecualian.
sumber
errorMessage
disetel ke "Not Found", tetapierrorCode
null.NoSuchKey
. Untuk daftar definitif kode kesalahan S3, lihat dokumentasi: docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.htmlMenggunakan AWS SDK gunakan metode getObjectMetadata. Metode ini akan menampilkan AmazonServiceException jika kuncinya tidak ada.
private AmazonS3 s3; ... public boolean exists(String path, String name) { try { s3.getObjectMetadata(bucket, getS3Path(path) + name); } catch(AmazonServiceException e) { return false; } return true; }
sumber
Di Amazon Java SDK 1.10+, Anda dapat menggunakan
getStatusCode()
untuk mendapatkan kode status respons HTTP, yaitu 404 jika objek tidak ada.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()
mengkonsumsi lebih sedikit sumber daya, dan respons tidak perlu ditutup sepertigetObject()
.Di versi sebelumnya, Anda dapat menggunakan
getErrorCode()
dan memeriksa string yang sesuai (tergantung versinya).sumber
Gunakan ListObjectsRequest setting Prefix sebagai kunci Anda.
Kode .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; } } }.
sumber
Untuk PHP (Saya tahu pertanyaannya adalah Java, tetapi Google membawa saya ke sini), Anda dapat menggunakan pembungkus aliran dan file_exists
$bucket = "MyBucket"; $key = "MyKey"; $s3 = Aws\S3\S3Client->factory([...]); $s3->registerStreamWrapper(); $keyExists = file_exists("s3://$bucket/$key");
sumber
Kode java ini memeriksa apakah kunci (file) ada di bucket 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; }
sumber
Hancurkan jalan Anda menjadi keranjang dan objek. Menguji keranjang menggunakan metode
doesBucketExist
, Menguji objek menggunakan ukuran daftar (0 jika tidak ada). Jadi kode ini akan melakukan:String bucket = ...; String objectInBucket = ...; AmazonS3 s3 = new AmazonS3Client(...); return s3.doesBucketExist(bucket) && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
sumber
Menggunakan Object isting. Fungsi Java untuk memeriksa apakah kunci yang ditentukan ada di AWS S3.
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; }
sumber
Cara yang tepat untuk melakukannya di SDK V2, tanpa kelebihan beban untuk benar-benar mendapatkan objek, adalah dengan menggunakan S3Client.headObject . Secara resmi didukung oleh AWS Change Log .
Kode contoh:
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; } }
sumber
Ada cara mudah untuk melakukannya menggunakan metode isObjectInBucket () jetS3t API.
Kode sampel:
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 }
sumber
Jawaban lainnya adalah untuk AWS SDK v1. Berikut adalah metode untuk AWS SDK v2 (saat ini 2.3.9).
Perhatikan bahwa
getObjectMetadata
dandoesObjectExist
metode saat ini tidak ada di v2 SDK! Jadi itu bukan lagi pilihan. Kami terpaksa menggunakan salah satugetObject
ataulistObjects
.listObjects
panggilan saat ini 12,5 kali lebih mahal untuk dibuat daripadagetObject
. Namun AWS juga mengenakan biaya untuk data apa pun yang diunduh, yang menaikkan hargagetObject
jika file tersebut ada . Selama file tersebut sangat tidak mungkin ada (misalnya, Anda telah membuat kunci UUID baru secara acak dan hanya perlu memeriksa ulang bahwa itu tidak diambil) lalu memanggilgetObject
secara signifikan lebih murah menurut perhitungan saya.Untuk berjaga-jaga, saya menambahkan
range()
spesifikasi untuk meminta AWS hanya mengirim beberapa byte file. Sejauh yang saya tahu, SDK akan selalu menghormati ini dan tidak menagih Anda untuk mengunduh seluruh file. Tetapi saya belum memverifikasi bahwa jadi andalkan perilaku itu dengan risiko Anda sendiri! (Selain itu, saya tidak yakin bagaimanarange
perilakunya jika objek S3 memiliki panjang 0 byte.)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; } }
Catatan: kode ini mengasumsikan
s3Client
danlog
dideklarasikan serta diinisialisasi di tempat lain. Metode mengembalikan boolean, tetapi dapat memunculkan pengecualian.sumber
s3Client.headObject()
di V2 untuk melakukan ini: stackoverflow.com/a/56949742/9814131 , dan Anda akan memeriksaS3Exception
kode status 404 untuk memeriksa apakah objek ada sesuai dengan masalah github github.com/aws/aws-sdk- java-v2 / issues / 297 . Tapi saya rasa milik Anda lebih progresif karena memiliki overhead yang sangat sedikit seperti 0-3 byte.Saya juga menghadapi masalah ini saat saya menggunakannya
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder);
Saya mendapat kunci kesalahan tidak ditemukan
Saat aku memukul dan mencoba
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder+"/");
berhasil, kode ini bekerja dengan 1.9 jar jika tidak perbarui ke 1.11 dan gunakan doesObjectExist seperti yang dikatakan di atas
sumber
Seperti yang disebutkan orang lain, untuk AWS S3 Java SDK 2.10+ Anda dapat menggunakan objek HeadObjectRequest untuk memeriksa apakah ada file di bucket S3 Anda. Ini akan bertindak seperti permintaan GET tanpa benar-benar mendapatkan file tersebut.
Contoh kode karena orang lain belum benar-benar menambahkan kode apa pun di atas:
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; } }
sumber
headObjectResponse
sama sekali.throws Exception
tidak dibutuhkan juga.Atau Anda dapat menggunakan Minio-Java klien , Sumber Terbuka dan kompatibel dengan API AWS S3.
Anda dapat menggunakan Minio-Java StatObject.java contoh untuk hal yang sama.
Saya harap ini membantu.
Penafian: Saya bekerja untuk Minio
sumber