Как проверить, существует ли указанный ключ в данной корзине S3 с помощью Java


Я хотел бы проверить, существует ли ключ в данной корзине, используя Java. Я посмотрел на API, но там нет никаких полезных методов. Я попытался использовать getObject, но это вызвало исключение.

13 60

13 ответов:

Используйте библиотеку jets3t. Он намного проще и надежнее, чем AWS sdk. Используя эту библиотеку, вы можете вызвать s3service.getObjectDetails (). Это позволит проверить и извлечь только детали объекта (не содержимое) объекта. Он выбросит 404, если объект отсутствует. Таким образом, вы можете поймать это исключение и справиться с ним в своем приложении.

Но для того, чтобы это работало, вам нужно будет иметь доступ к ListBucket для пользователя на этом ведре. Просто GetObject access не будет работать. Причина в том, что Amazon не позволит вам проверить наличие ключа, если у вас нет доступа к ListBucket. Просто зная, присутствует ли ключ или нет, также будет достаточно для вредоносных пользователей в некоторых случаях. Следовательно, если у них нет доступа к ListBucket, они не смогут этого сделать.

Теперь в официальном Java API есть метод doobjectexist.

Наслаждайтесь!

Использовать 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 для проверки этого потока-только документацию об исключении.

Использование 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();
    S3Object 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;
            }
        }
    }.

Для PHP (я знаю, что вопрос в Java, но Google привел меня сюда), вы можете использовать stream wrappers и 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;
}

Использование объекта 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;
    }

Разбейте свой путь на ведро и объект. Тестирование ковша с помощью метода doesBucketExist, Тестирование объекта с использованием размера списка (0 в случае отсутствия). Так что этот код будет делать:

String bucket = ...;
String objectInBucket = ...;
AmazonS3 s3 = new AmazonS3Client(...);
return s3.doesBucketExist(bucket) 
       && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();

Есть простой способ сделать это с помощью метода 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

        }

В качестве альтернативы вы можете использовать клиентскую библиотекуMinio-Java с открытым исходным кодом, совместимую с API AWS S3.

Вы можете использовать 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)
    throws NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException, MinioException {
    // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
    // dummy values, please replace them with original values.
    // Set s3 endpoint, region is calculated automatically
    MinioClient s3Client = new MinioClient("https://s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY");
    InputStream stream = s3Client.getObject("my-bucketname", "my-objectname");

    byte[] buf = new byte[16384];
    int bytesRead;
    while ((bytesRead = stream.read(buf, 0, buf.length)) >= 0) {
      System.out.println(new String(buf, 0, bytesRead));
    }

    stream.close();
  }
}

Надеюсь, это поможет.

Отказ от ответственности: я работаю на Minio

Используйте метод dobucketexist S3Client в AWS SDK

  static final AmazonS3 S3_CLIENT = AmazonS3ClientBuilder.defaultClient();
    if (!S3_CLIENT.doesBucketExist(bucketName)) {
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName, region);
            Bucket bucket = S3_CLIENT.createBucket(createBucketRequest);

            logger.log("Created Bucket Name" + bucket.getName() + " | Creation :" + bucket.getCreationDate());
        }

Надеюсь, это поможет.