Other answers for AWS SDK v1. Here is the method for AWS SDK v2 (currently 2.3.9).
Please note that getObjectMetadata and doesObjectExist are currently missing in the SDK v2! So these are no longer options. We are forced to use either getObject or listObjects .
listObjects is currently 12.5 times more expensive than getObject . But AWS also charges for any uploaded data, which increases the cost of getObject if the file exists. While the file is unlikely to exist (for example, you generated a new UUID key randomly, and you just need to double check that it was not taken), then calling getObject much cheaper by my calculations.
However, to be safe, I added the range() specification to ask AWS to send only a few bytes of the file. As far as I know, the SDK will always respect this and will not charge a fee for downloading the entire file. But I did not test this, so rely on this behavior at your own peril and risk! (Also, I'm not sure how range behaves if the S3 object is 0 bytes long.)
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; } }
Note: this code assumes that s3Client and log declared and initialized elsewhere. The method returns a boolean, but may throw exceptions.
Bampfer Feb 02 '19 at 0:47 2019-02-02 00:47
source share