Java kullanan belirli bir pakette bir anahtar olup olmadığını kontrol etmek istiyorum. API'ye baktım ama faydalı olan herhangi bir yöntem yok. Kullanmaya çalıştım getObject
ama bir istisna yarattı.
Java kullanan belirli bir pakette bir anahtar olup olmadığını kontrol etmek istiyorum. API'ye baktım ama faydalı olan herhangi bir yöntem yok. Kullanmaya çalıştım getObject
ama bir istisna yarattı.
Yanıtlar:
Jets3t kitaplığını kullanın. AWS sdk'den çok daha kolay ve sağlamdır. Bu kitaplığı kullanarak s3service.getObjectDetails () öğesini çağırabilirsiniz. Bu, yalnızca nesnenin ayrıntılarını (içeriğini değil) kontrol edecek ve alacaktır. Nesne eksikse 404 atar. Böylece bu istisnayı yakalayabilir ve uygulamanızda bununla başa çıkabilirsiniz.
Ancak bunun çalışması için, o paketteki kullanıcı için ListBucket erişimine sahip olmanız gerekir. Sadece GetObject erişimi çalışmayacak. Bunun nedeni, ListBucket erişiminiz yoksa Amazon, anahtarın varlığını kontrol etmenizi engelleyecektir. Sadece bir anahtarın var olup olmadığını bilmek, bazı durumlarda kötü niyetli kullanıcılar için de yeterli olacaktır. Bu nedenle, ListBucket erişimine sahip olmadıkça, bunu yapamazlar.
Artık resmi Java API'sinde bir doObjectExist yöntemi var.
Zevk almak!
doesObjectExist
, 2.x SDK'dan (şu anda v2.3.9) kaldırılmış .
Güncelleme:
Görünüşe göre tam da bunu kontrol etmek için yeni bir API var. Bu sayfada başka bir cevaba bakın: https://stackoverflow.com/a/36653034/435605
Orijinal gönderi:
Kullanım 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);
}
İstisna hakkında not: İstisnaların akış kontrolü için kullanılmaması gerektiğini biliyorum. Sorun şu ki, Amazon bu akışı kontrol etmek için herhangi bir API sağlamadı - sadece istisna hakkında belgeler.
errorMessage
"Bulunamadı" olarak ayarlandığını görüyorum , ancak errorCode
null.
NoSuchKey
. S3 hata kodlarının kesin listesi için dokümantasyona bakın: docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
AWS SDK'yı kullanarak getObjectMetadata yöntemini kullanın. Anahtar yoksa, yöntem bir AmazonServiceException oluşturur.
private AmazonS3 s3;
...
public boolean exists(String path, String name) {
try {
s3.getObjectMetadata(bucket, getS3Path(path) + name);
} catch(AmazonServiceException e) {
return false;
}
return true;
}
Amazon Java SDK 1.10+ içinde, getStatusCode()
nesne yoksa 404 olacak olan HTTP yanıtının durum kodunu almak için kullanabilirsiniz .
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()
daha az kaynak tüketir ve yanıtın kapatılmasına gerek yoktur getObject()
.
Önceki sürümlerde, getErrorCode()
uygun dizeyi kullanabilir ve kontrol edebilirsiniz (sürüme bağlıdır).
Anahtarınız olarak ListObjectsRequest ayarı Önekini kullanın.
.NET kodu:
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;
}
}
}.
PHP için (Sorunun Java olduğunu biliyorum, ancak Google beni buraya getirdi), akış sarmalayıcıları ve file_exists'i kullanabilirsiniz
$bucket = "MyBucket";
$key = "MyKey";
$s3 = Aws\S3\S3Client->factory([...]);
$s3->registerStreamWrapper();
$keyExists = file_exists("s3://$bucket/$key");
Bu java kodu, anahtarın (dosyanın) s3 paketinde mevcut olup olmadığını kontrol eder.
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;
}
Yolunuzu kova ve nesneye ayırın. Yöntemi kullanarak kovayı doesBucketExist
test etme, Listenin boyutunu kullanarak nesneyi test etme (yoksa 0). Yani bu kod şunları yapacak:
String bucket = ...;
String objectInBucket = ...;
AmazonS3 s3 = new AmazonS3Client(...);
return s3.doesBucketExist(bucket)
&& !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
Object isting'i kullanma. AWS S3'te belirtilen anahtarın mevcut olup olmadığını kontrol etmek için Java işlevi.
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;
}
Bunu SDK V2'de, nesneyi gerçekten alma aşırı yüklemesi olmadan yapmanın doğru yolu, S3Client.headObject'i kullanmaktır . Resmi olarak AWS Değişiklik Günlüğü ile desteklenir .
Örnek kod:
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;
}
}
JetS3t API'sinin isObjectInBucket () yöntemini kullanarak bunu yapmanın kolay bir yolu vardır.
Basit kod:
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
}
Diğer yanıtlar AWS SDK v1 içindir. İşte AWS SDK v2 (şu anda 2.3.9) için bir yöntem.
Bunun getObjectMetadata
ve doesObjectExist
yöntemlerin şu anda v2 SDK'da olmadığını unutmayın ! Yani bunlar artık seçenekler değil. Ya getObject
da kullanmak zorunda kalıyoruz listObjects
.
listObjects
şu anda arama yapmaktan 12,5 kat daha pahalıdır getObject
. Ancak AWS, indirilen tüm veriler için de ücret alır ve getObject
bu, dosyanın mevcut olup olmadığının fiyatını yükseltir . Dosyanın var olma olasılığı çok düşük olduğu sürece (örneğin, rastgele yeni bir UUID anahtarı oluşturdunuz ve alınmadığını iki kez kontrol etmeniz gerekiyor), bu durumda arama getObject
hesaplamama göre önemli ölçüde daha ucuz.
Yine de güvenli tarafta olmak için, range()
AWS'den dosyanın yalnızca birkaç baytını göndermesini istemek için bir şartname ekledim . Bildiğim kadarıyla, SDK buna her zaman saygı duyacak ve tüm dosyayı indirdiğiniz için sizden ücret talep etmeyecektir. Ama bu davranışa kendi sorumluluğunuzda güvendiğinizi doğrulamadım! (Ayrıca, range
S3 nesnesi 0 bayt uzunluğundaysa nasıl davranacağından emin değilim .)
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;
}
}
Not: Bu kod varsayar s3Client
ve log
başka yerlerde ilan ve başlatılır. Yöntem bir boole döndürür, ancak istisnalar atabilir.
s3Client.headObject()
V2'de bunu yapacak bir tane var: stackoverflow.com/a/56949742/9814131 ve S3Exception
nesnenin github sorununa göre var olup olmadığını kontrol etmek için 404 durum kodunu kontrol edeceksiniz github.com/aws/aws-sdk- java-v2 / sorunlar / 297 . Ama sanırım sizinki 0-3 bayt kadar az ek yükü olduğu için daha ilerici.
Ben de kullandığımda bu problemle karşılaştım
String BaseFolder = "3patti_Logs";
S3Object object = s3client.getObject(bucketName, BaseFolder);
Hata anahtarı bulunamadı
Vurup denediğimde
String BaseFolder = "3patti_Logs";
S3Object object = s3client.getObject(bucketName, BaseFolder+"/");
işe yaradı, bu kod 1.9 jar ile çalışıyor, aksi takdirde 1.11'e güncelleyin ve yukarıda belirtildiği gibi doObjectExist'i kullanın
Diğerlerinin de belirttiği gibi, AWS S3 Java SDK 2.10+ için, S3 klasörünüzde bir dosya olup olmadığını kontrol etmek için HeadObjectRequest nesnesini kullanabilirsiniz . Bu, dosyayı gerçekten almadan bir GET isteği gibi davranacaktır.
Başkaları aslında yukarıya herhangi bir kod eklemediği için örnek kod:
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;
}
}
headObjectResponse
. throws Exception
ayrıca gerekli değildir.
Alternatif olarak Minio-Java kullanabilirsiniz istemci kitaplığını, Açık Kaynağını ve AWS S3 API ile uyumlu kullanabilirsiniz.
Minio-Java StatObject.java'yı kullanabilirsiniz. örneklerini .
io.minio.MinioClient'i içe aktar; import io.minio.errors.MinioException; java.io.InputStream'i içe aktarın; java.io.IOException'ı içe aktarın; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import org.xmlpull.v1.XmlPullParserException; public class GetObject { public static void main (String [] değiştirgeler) NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException, MinioException { // Not: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY ve benim-paketim // sahte değerler, lütfen bunları orijinal değerlerle değiştirin. // s3 uç noktası ayarlayın, bölge otomatik olarak hesaplanır MinioClient s3Client = new MinioClient ("https://s3.amazonaws.com", "ERİŞİM ANAHTAR KİMLİĞİNİZ", "SECRETACCESSKEYİNİZ"); InputStream stream = s3Client.getObject ("paket adım", "nesne adım"); bayt [] buf = yeni bayt [16384]; int bytesRead; while ((bytesRead = stream.read (buf, 0, buf.length))> = 0) { System.out.println (new String (buf, 0, bytesRead)); } stream.close (); } }
Umut ediyorum bu yardım eder.
Feragatname: Minio için çalışıyorum