Я хотел бы проверить, существует ли ключ в данном ведре, используя Java. Я посмотрел API, но нет никаких полезных методов. Я попытался использовать, getObject
но возникла исключительная ситуация.
java
amazon-web-services
amazon-s3
aws-sdk
по его стопам
источник
источник
Ответы:
Используйте библиотеку jets3t. Это намного проще и надежнее, чем AWS sdk. Используя эту библиотеку, вы можете вызвать s3service.getObjectDetails (). Это будет проверять и извлекать только детали объекта (не содержимое) объекта. Если объект отсутствует, он выдаст ошибку 404. Таким образом, вы можете перехватить это исключение и обработать его в своем приложении.
Но для того, чтобы это работало, вам потребуется доступ к ListBucket для пользователя в этом сегменте. Просто получить доступ к GetObject не получится. Причина в том, что Amazon не позволит вам проверить наличие ключа, если у вас нет доступа к ListBucket. В некоторых случаях злоумышленникам достаточно просто знать, присутствует ли ключ или нет. Следовательно, если у них нет доступа к ListBucket, они не смогут этого сделать.
источник
Теперь в официальном API Java есть метод doesObjectExist .
Наслаждайтесь!
источник
doesObjectExist
из SDK 2.x (в настоящее время v2.3.9).Обновить:
Кажется, есть новый 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 для проверки этого потока - только документация об исключении.
источник
errorMessage
установлено значение «Not Found», ноerrorCode
это null.NoSuchKey
. ПолныйИспользуя 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; }
источник
В 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()
и проверять соответствующую строку (в зависимости от версии).источник
Используйте параметр Prefix 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; } } }.
источник
Для PHP (я знаю, что это Java, но Google привел меня сюда) вы можете использовать обертки потока и file_exists
$bucket = "MyBucket"; $key = "MyKey"; $s3 = Aws\S3\S3Client->factory([...]); $s3->registerStreamWrapper(); $keyExists = file_exists("s3://$bucket/$key");
источник
Этот код 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; }
источник
Разбейте свой путь на ведро и объект. Тестирование корзины с использованием метода
doesBucketExist
Тестирование объекта с использованием размера листинга (0 в случае, если не существует). Итак, этот код будет делать:String bucket = ...; String objectInBucket = ...; AmazonS3 s3 = new AmazonS3Client(...); return s3.doesBucketExist(bucket) && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
источник
Использование Object isting. Функция Java для проверки наличия указанного ключа в 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; }
источник
Есть простой способ сделать это, используя метод isObjectInBucket () API JetS3t.
Образец кода:
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
если файл существует . Пока файл вряд ли существует (например, вы случайно сгенерировали новый ключ 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
объявляется и инициализируется в другом месте. Метод возвращает логическое значение, но может вызывать исключения.источник
s3Client.headObject()
в V2 есть для этого: stackoverflow.com/a/56949742/9814131 , и вы проверитеS3Exception
код состояния 404, чтобы проверить, существует ли объект в соответствии с проблемой github github.com/aws/aws-sdk- Ява-v2 / вопросы / 297 . Но я думаю, ваши более прогрессивные, поскольку у них очень мало накладных расходов, как 0–3 байта.Правильный способ сделать это в SDK V2 без перегрузки фактического получения объекта - использовать S3Client.headObject . Официально поддерживается AWS Change Log .
источник
Я тоже столкнулся с этой проблемой, когда использовал
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder);
У меня ошибка, ключ не найден
Когда я бью и пытаюсь
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder+"/");
это сработало, этот код работает с 1.9 jar, в противном случае обновите до 1.11 и используйте doObjectExist, как указано выше
источник
Как уже упоминалось, для 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; } }
источник
headObjectResponse
.throws Exception
тоже не нужен.В качестве альтернативы вы можете использовать клиентскую библиотеку Minio-Java , ее открытый исходный код и совместимую с AWS S3 API.
Для этого вы можете использовать примеры Minio-Java StatObject.java .
Я надеюсь, что это помогает.
Отказ от ответственности: я работаю на Minio
источник