Я хотел бы проверить, существует ли ключ в данном ведре, используя Java. Я посмотрел API, но нет никаких полезных методов. Я попытался использовать, getObject
но возникла исключительная ситуация.
Я хотел бы проверить, существует ли ключ в данном ведре, используя Java. Я посмотрел API, но нет никаких полезных методов. Я попытался использовать, getObject
но возникла исключительная ситуация.
Ответы:
Используйте библиотеку 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;
}
}
}.
Этот код 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 .
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) выдает исключение NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException, MinioException { // Примечание: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY и my-bucketname являются // фиктивные значения, замените их исходными значениями. // Устанавливаем конечную точку s3, регион рассчитывается автоматически MinioClient s3Client = новый MinioClient («https://s3.amazonaws.com», «YOUR-ACCESSKEYID», «YOUR-SECRETACCESSKEY»); InputStream stream = s3Client.getObject ("my-bucketname", "my-objectname"); byte [] buf = новый байт [16384]; int bytesRead; while ((bytesRead = stream.read (buf, 0, buf.length))> = 0) { System.out.println (новая строка (buf, 0, bytesRead)); } stream.close (); } }
Я надеюсь, что это помогает.
Отказ от ответственности: я работаю на Minio