Reputation: 10122
I am familiar with AWS Java SDK, I also tried to browse the corresponding Javadoc, but I could not realize how do I create a sub directory, i.e., a directory object within a bucket, and how do I upload files to it.
Assume bucketName
and dirName
correspond to already existing bucket (with public permission) and a new (object) directory which needs to be created within the bucket (i.e. bucketName/dirName/)
I have tried the following:
AmazonS3Client s3 = new AmazonS3Client(
new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
s3.createBucket(bucketName + "/" + dirName); //throws exception
which throws an exception on the second line.
A short snippet which creates a sub-directory and uploads files to it will be deeply appreciated.
Upvotes: 37
Views: 66340
Reputation: 173
You may use below snippet in JAVA SDK V2:
PutObjectRequest por = PutObjectRequest.builder()
.bucket("bucketName")
.key("dirName")
.build();
s3Client.putObject(por, RequestBody.empty());
Note: dirName must end with /
to be considered as a folder in S3
Upvotes: 1
Reputation: 2418
This worked for me. I used spring boot and file uploaded according to Multipart mechanism. I wanted to save my images inside the photos folder in my aws s3 bucket. My need is save like this photos/mypic.jpg
----controller class method----
@PostMapping("/uploadFile")
public String uploadFile(@RequestPart(value = "file") MultipartFile file) throws IOException {
return this.amazonClient.uploadFile(file);
}
----service class (Implementation of controller)----
public String uploadFile(MultipartFile multipartFile) throws IOException {
try {
File file = convertMultiPartToFile(multipartFile);
String fileName = "photoes/"+generateFileName(multipartFile); //here give any folder name you want
uploadFileTos3bucket(fileName, file);
} catch (AmazonServiceException ase) {
logger.info("Caught an AmazonServiceException from GET requests, rejected reasons:");
}
return fileName;
}
The point is concatenate the folder name you want as prefix of the fileName
additionally I will show you how to delete folder. The point is give the folder name as the keyName(key name is uploaded object name in the s3 bucket.). I will show code snippet also.
----controller class method----
@DeleteMapping("/deleteFile")
public String deleteFile(@RequestPart(value = "keyName") String keyName) {
return this.amazonClient.deleteFile(keyName);
}
----service class (Implementation of controller)----
public String deleteFile(String keyName){
try {
s3client.deleteObject(new DeleteObjectRequest(bucketName, keyName));
} catch (SdkClientException e) {
e.printStackTrace();
}
return "deleted file successfully!";
}
for delete photos folder that we created , call method like this. deleteFile("photos/")
important:- / is mandatory
Upvotes: 0
Reputation: 484
Leaving this answer here just in case someone stumbles upon this. I have been using aws sdk version - 1.11.875 and the following successfully created a folder for me when trying to upload a file into S3 bucket. I did not have to explicitly create the folder as mentioned in the earlier answer.
private void uploadFileToS3Bucket(final String bucketName, final File file) {
final String fileName = "parent/child/" + file.getName();
final PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, file);
amazonS3.putObject(putObjectRequest);
}
This will create the parent and parent/child folders in the specified S3 bucket and upload the file into child folder.
Upvotes: 1
Reputation: 1684
In newer versions of the SDK, you can do something like this (no need to create empty InputStream) to create an empty folder:
String key = parentKey + newFolderName;
if (!StringUtils.endsWith(key, "/")) {
key += "/";
}
PutObjectRequest putRequest = PutObjectRequest.builder()
.bucket(parent.getBucket())
.key(key)
.acl("public-read")
.build();
s3Client.putObject(putRequest, RequestBody.empty());
Upvotes: 6
Reputation: 82
if You want to create folder then you need to use put command using following keys to create folder1 in:
in root of bucket -> folder1/folder1_$folder$
in path folder2/folder3/ -> folder2/folder3/folder1/folder1_$folder$
It is always all_previous_folders/folderName/folderName_$folder$
Upvotes: -2
Reputation: 1225
S3 doesn't see directories in the traditional way we do this on our operating systems. Here is how you can create a directory:
public static void createFolder(String bucketName, String folderName, AmazonS3 client) {
// create meta-data for your folder and set content-length to 0
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(0);
// create empty content
InputStream emptyContent = new ByteArrayInputStream(new byte[0]);
// create a PutObjectRequest passing the folder name suffixed by /
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
folderName + SUFFIX, emptyContent, metadata);
// send request to S3 to create folder
client.putObject(putObjectRequest);
}
As casablanca already said you can upload files to directories like this:
s3.putObject("someBucket", "foo/bar1", file1);
Read the whole tutorial here for details, and the most important thing is you will find info how to delete the directories.
Upvotes: 36
Reputation: 70731
There are no "sub-directories" in S3. There are buckets and there are keys within buckets.
You can emulate traditional directories by using prefix searches. For example, you can store the following keys in a bucket:
foo/bar1
foo/bar2
foo/bar3
blah/baz1
blah/baz2
and then do a prefix search for foo/
and you will get back:
foo/bar1
foo/bar2
foo/bar3
See AmazonS3.listObjects
for more details.
Update: Assuming you already have an existing bucket, the key under that bucket would contain the /
:
s3.putObject("someBucket", "foo/bar1", file1);
s3.putObject("someBucket", "foo/bar2", file2);
...
Then you can list all keys starting with foo/
:
ObjectListing listing = s3.listObjects("someBucket", "foo/");
Upvotes: 57