मैं यह जांचना चाहूंगा कि क्या जावा का उपयोग करके किसी दिए गए बाल्टी में एक कुंजी मौजूद है। मैंने एपीआई को देखा लेकिन कोई भी तरीका उपयोगी नहीं है। मैंने उपयोग करने की कोशिश की getObject
लेकिन इसने एक अपवाद फेंक दिया।
मैं यह जांचना चाहूंगा कि क्या जावा का उपयोग करके किसी दिए गए बाल्टी में एक कुंजी मौजूद है। मैंने एपीआई को देखा लेकिन कोई भी तरीका उपयोगी नहीं है। मैंने उपयोग करने की कोशिश की getObject
लेकिन इसने एक अपवाद फेंक दिया।
जवाबों:
जेट 3 टी लाइब्रेरी का उपयोग करें। यह एडब्ल्यूएस एसडीके की तुलना में बहुत अधिक आसान और मजबूत है। इस लाइब्रेरी का उपयोग करके आप कॉल कर सकते हैं, s3service.getObjectDetails ()। यह ऑब्जेक्ट के केवल विवरण (सामग्री नहीं) की जाँच करेगा और पुनः प्राप्त करेगा। यदि ऑब्जेक्ट गायब है, तो यह 404 फेंक देगा। तो आप उस अपवाद को पकड़ सकते हैं और अपने ऐप में इससे निपट सकते हैं।
लेकिन इसके लिए काम करने के लिए, आपको उस बाल्टी पर उपयोगकर्ता के लिए ListBucket एक्सेस की आवश्यकता होगी। बस GetObject पहुँच काम नहीं करेगा। कारण है, अगर आप ListBucket पहुँच नहीं है, तो Amazon आपको कुंजी की उपस्थिति के लिए जाँच करने से रोकेगा। बस यह जानना कि कोई कुंजी मौजूद है या नहीं, कुछ मामलों में दुर्भावनापूर्ण उपयोगकर्ताओं के लिए भी पर्याप्त होगा। इसलिए जब तक उनके पास ListBucket एक्सेस नहीं है, वे ऐसा करने में सक्षम नहीं होंगे।
अब आधिकारिक जावा एपीआई में एक doObjectExist पद्धति है।
का आनंद लें!
doesObjectExist
2.x एसडीके (वर्तमान में v2.3.9) से हटा दिया गया है।
अपडेट करें:
ऐसा लगता है कि वहाँ एक नया एपीआई बस की जाँच करने के लिए है। इस पृष्ठ में एक और उत्तर देखें: 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);
}
अपवाद के बारे में ध्यान दें: मुझे पता है कि प्रवाह नियंत्रण के लिए अपवादों का उपयोग नहीं किया जाना चाहिए। समस्या यह है कि अमेज़ॅन ने इस प्रवाह की जांच करने के लिए कोई एपीआई प्रदान नहीं किया - केवल अपवाद के बारे में दस्तावेज।
errorMessage
"नहीं मिला" पर सेट है, लेकिन errorCode
अशक्त है।
NoSuchKey
। S3 त्रुटि कोड की एक निश्चित सूची के लिए, दस्तावेज़ देखें: docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
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;
}
अमेज़ॅन जावा एसडीके 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()
उपयुक्त स्ट्रिंग (संस्करण पर निर्भर करता है) के लिए उपयोग और जांच कर सकते हैं ।
अपनी कुंजी के रूप में 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;
}
}
}.
यह जावा कोड यह जांचता है कि कुंजी (फाइल) 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;
}
बाल्टी और वस्तु में अपना रास्ता तोड़ो। विधि का उपयोग करके बाल्टी का doesBucketExist
परीक्षण करना, लिस्टिंग के आकार का उपयोग करके वस्तु का परीक्षण करना (0 मौजूद नहीं होने की स्थिति में)। तो यह कोड करेगा:
String bucket = ...;
String objectInBucket = ...;
AmazonS3 s3 = new AmazonS3Client(...);
return s3.doesBucketExist(bucket)
&& !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
ऑब्जेक्ट का उपयोग करना। जावा फ़ंक्शन यह जाँचने के लिए कि निर्दिष्ट कुंजी 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;
}
जेटएस 3 टी एपीआई के आईओबजेक्ट इनबकेट () विधि का उपयोग करने का एक आसान तरीका है।
नमूना कोड:
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
}
अन्य जवाब AWS SDK v1 के लिए हैं। यहां AWS SDK v2 (वर्तमान में 2.3.9) के लिए एक विधि है।
ध्यान दें कि getObjectMetadata
और doesObjectExist
विधियाँ वर्तमान में v2 SDK में नहीं हैं! तो अब वे विकल्प नहीं हैं। हम getObject
या तो उपयोग करने के लिए मजबूर हैं याlistObjects
।
listObjects
वर्तमान में कॉल 12.5 गुना अधिक महंगी हैं getObject
। लेकिन AWS डाउनलोड किए गए किसी भी डेटा के लिए भी शुल्क लेता है, जो getObject
फ़ाइल मौजूद होने पर कीमत बढ़ाता है । जब तक फ़ाइल मौजूद होने की बहुत संभावना नहीं है (उदाहरण के लिए, आपने एक नई यूयूआईडी कुंजी को यादृच्छिक रूप से उत्पन्न किया है और बस यह जांचने की आवश्यकता है कि इसे नहीं लिया गया है) फिर कॉल करनाgetObject
मेरी गणना से काफी सस्ती है।
बस सुरक्षित पक्ष पर होने के लिए, मैंने range()
एडब्ल्यूएस को केवल फ़ाइल के कुछ बाइट्स भेजने के लिए कहने के लिए एक विनिर्देश जोड़ा । जहां तक मुझे पता है एसडीके हमेशा इसका सम्मान करेगा और आपसे पूरी फाइल डाउनलोड करने के लिए शुल्क नहीं लेगा। लेकिन मैंने यह सत्यापित नहीं किया है कि आपके जोखिम पर उस व्यवहार पर भरोसा करें! (इसके अलावा, मुझे यकीन नहीं है कि 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
अन्यत्र घोषित और आरंभिक है। विधि एक बूलियन देता है, लेकिन अपवाद फेंक सकता है।
s3Client.headObject()
V2 में है: stackoverflow.com/a/56949742/9814131 , और आप जाँचेंगे कि क्या S3Exception
स्थिति github.com/aws/aws-sdk- के अनुसार वस्तु मौजूद है , यह जाँचने के लिए कोड 404 की जाँच करेंगे। java-v2 / मुद्दों / 297 । लेकिन मुझे लगता है कि तुम्हारा अधिक प्रगतिशील है क्योंकि यह 0-3 बाइट्स के रूप में बहुत कम ओवरहेड है।
SDK V2 में इसे करने का सही तरीका, वास्तव में ऑब्जेक्ट को अधिभार के बिना, S3Client.headOffject का उपयोग करना है । आधिकारिक तौर पर AWS चेंज लॉग द्वारा समर्थित है ।
जब मैंने इस्तेमाल किया तो मुझे भी इस समस्या का सामना करना पड़ा
String BaseFolder = "3patti_Logs";
S3Object object = s3client.getObject(bucketName, BaseFolder);
मुझे त्रुटि कुंजी मिली नहीं मिली
जब मैंने मारा और कोशिश की
String BaseFolder = "3patti_Logs";
S3Object object = s3client.getObject(bucketName, BaseFolder+"/");
यह काम किया, यह कोड 1.9 जार के साथ काम कर रहा है अन्यथा 1.11 पर अपडेट करें और ऊपर बताए अनुसार doObjectExist का उपयोग करें
जैसा कि दूसरों ने उल्लेख किया है, एडब्ल्यूएस एस 3 जावा एसडीके 2.10+ के लिए आप यह जांचने के लिए हेडऑबजेक्ट रिस्पेक्ट ऑब्जेक्ट का उपयोग कर सकते हैं कि क्या आपके एस 3 बाल्टी में कोई फ़ाइल है। यह वास्तव में फ़ाइल प्राप्त किए बिना 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;
}
}
headObjectResponse
। throws Exception
साथ ही जरूरत नहीं है।
वैकल्पिक रूप से आप Minio-Java क्लाइंट लाइब्रेरी, इसके ओपन सोर्स और AWS S3 API के साथ संगत का उपयोग कर सकते हैं ।
आप उसी के लिए Minio-Java StatObject.java उदाहरणों का उपयोग कर सकते हैं ।
आयात io.minio.MinioClient; आयात io.minio.errors.MinioException; आयात java.io.InputStream; आयात java.io.IOException; आयात java.security.NoSuchAlgorithmException; आयात java.security.InvalidKeyException; import org.xmlpull.v1.XmlPullParserException; सार्वजनिक वर्ग GetObject { सार्वजनिक स्थैतिक शून्य main (String [] args) NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException, MinioException {फेंकता है // नोट: आपका-ACCESSKEYID, आपका- SECRETACCESSKEY और my-bucketname हैं // डमी मान, कृपया उन्हें मूल मानों से बदलें। // सेट s3 समापन बिंदु, क्षेत्र की गणना स्वचालित रूप से की जाती है MinioClient s3Client = new MinioClient ("https://s3.amazonaws.com", "Your-ACCESSKEYID", "Your-SECRETACCESSKEY"); InputStream स्ट्रीम = s3Client.getObject ("my-bucketname", "my-objectname"); बाइट [] बफ = नई बाइट [16384]; int बाइट्स रीड; जबकि (bytesRead = stream.read (buf, 0, buf.length))> = 0) { System.out.println (नया स्ट्रिंग (buf, 0, बाइट्स रीड)); } stream.close (); } }
मुझे उम्मीद है यह मदद करेगा।