如何使用AWS SDK为Node.js在s3上创建文件夹或密钥?

时间:2021-10-05 10:41:46

I'm using AWS SDK for Node.js to create a folder or key on s3. I searched on google, but I got nothing. Does anybody know how can I create a folder under my bucket with AWS SDK for Node.js? and how can you check if this folder exists in your bucket already?

我正在用AWS SDK进行节点。在s3上创建文件夹或键。我搜索了谷歌,但什么也没找到。有人知道我如何为Node.js创建一个包含AWS SDK的文件夹吗?如何检查这个文件夹是否已经存在于您的bucket中呢?

if you use console.aws.amazon.com, you can create a folder in your bucket easily. it seems I didn't figure it out how to create it with AWS SDK for Node.js?

如果你使用console.aws.amazon.com,你可以很容易地在你的bucket中创建一个文件夹。好像我还没想好如何用AWS SDK为Node.js创建它?

4 个解决方案

#1


28  

S3 does not have folders or files; it has buckets and objects. Buckets are used to store objects, and objects comprise data (which can be a file) and metadata (information about the data).

S3没有文件夹或文件;它有桶和物体。存储桶用于存储对象,对象包含数据(可以是文件)和元数据(关于数据的信息)。

You don't need to pre-create a folder structure in S3. You can simply put an object with key=cars/ford/sedans/focus.png even if cars/ford/sedans/ does not exist. In this case:

您不需要在S3中预先创建文件夹结构。你可以简单地用key=cars/ford/sedans/focus来放置一个对象。即使汽车/福特/轿车/不存在png。在这种情况下:

  • the putObject call will create an object at cars/ford/sedans/focus.png but it will not create anything representing the intermediate folder structure of cars/ford/sedans/.

    putObject调用将在cars/ford/sedans/focus中创建一个对象。但是它不会创建任何表示汽车/福特/轿车/中间文件夹结构的东西。

  • the actual folder structure does not exist, but is implied through your use of delimiter=/ in your calls to listObjects, and the folders will be returned in CommonPrefixes while the files will be returned in Contents.

    实际的文件夹结构不存在,但通过调用listObjects时使用delimiter=/来表示,文件夹将在CommonPrefixes中返回,而文件将在内容中返回。

  • you will not be able to test for the sedans sub-folder using headObject because cars/ford/sedans/ does not actually exist (it is not an object). Instead you have two options:

    您将无法使用headObject对轿车子文件夹进行测试,因为汽车/福特/轿车/轿车实际上并不存在(它不是一个对象)。相反,你有两个选择:

    • call listObjects with prefix=cars/ford/sedans/ and then find it in Contents, or
    • 调用前缀为=cars/ford/sedans/然后在内容中找到它
    • call listObjects with prefix=cars/ford/, delimiter=/ and then find it in CommonPrefixes.
    • 调用具有前缀=cars/ford/、delimiter=/的listobject,然后在CommonPrefixes中找到它。

It is, however, possible to create an S3 object that represents a folder, if you really want to. To create myfolder in a bucket named mybucket, you can issue a putObject call with bucket=mybucket and key=myfolder/. Note the trailing forward slash. In this case:

但是,如果您确实需要,可以创建一个表示文件夹的S3对象。要在一个名为mybucket的桶中创建myfolder,您可以使用bucket=mybucket和key=myfolder/来发出putObject调用。注意后面的斜线。在这种情况下:

  • the folder is actually a zero-sized object whose key ends in /. Note that if you leave off the trailing / then you will get a zero-sized object that appears to be a file rather than a folder.

    文件夹实际上是一个大小为零的对象,其键以/结尾。请注意,如果您省略了尾随/之后,您将得到一个看起来是文件而不是文件夹的零大小对象。

  • you can test for the presence of myfolder/subfolder/ in mybucket by issuing a headObject call with bucket=mybucket and key=myfolder/subfolder/.

    通过使用bucket和key=myfolder/子文件夹/子文件夹/子文件夹/发出一个headObject调用,可以测试myfolder/子文件夹/在mybucket中的存在性。

Finally, note that your folder delimiter can be anything you like, for example +, because it is simply part of the key and is not actually a folder separator (there are no folders). You can vary your folder delimiter from listObjects call to call if you like.

最后,请注意,您的文件夹分隔符可以是您喜欢的任何东西,例如+,因为它只是键的一部分,实际上并不是一个文件夹分隔符(没有文件夹)。如果您愿意,可以将您的文件夹分隔符从listObjects调用更改为call。

#2


14  

The code from @user2837831 doesn't seem to work anymore, probably with the new version of javascript sdk. So I am adding here the version of code that I am using to create a folder inside a bucket using node.js. This works with the 2.1.31 sdk. What is important is the '/' at the end of the Key value in params - using that it thinks you are trying to create a folder and not a file.

@user2837831的代码似乎不再有用了,可能是新版本的javascript sdk。所以我在这里添加了我用来在bucket中使用node.js创建文件夹的代码版本。这适用于2.1.31 sdk。重要的是params中键值末尾的'/'——使用它会认为您正在创建一个文件夹,而不是一个文件。

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var s3Client = new AWS.S3();

var params = { Bucket: 'your_bucket_goes_here', Key: 'folderInBucket/', ACL: 'public-read', Body:'body does not matter' };

s3Client.upload(params, function (err, data) {
if (err) {
    console.log("Error creating the folder: ", err);
    } else {
    console.log("Successfully created a folder on S3");

    }
});

#3


8  

A folder in a bucket is just another bucket. So you can use headBucket to check if it exists and create it with createBucket if it doesn't. Something like this:

bucket中的文件夹就是另一个bucket。因此,您可以使用headBucket检查它是否存在,如果不存在,可以使用createBucket创建它。是这样的:

var AWS = require('aws-sdk'),
    s3 = new AWS.S3(),
    bucketFolder = 'bucketA/folderInBucketA';

s3.headBucket({Bucket:bucketFolder},function(err,data){
    if(err){
        s3.createBucket({Bucket:bucketFolder},function(err,data){
            if(err){ throw err; }
            console.log("Bucket created");
        });
     } else {
         console.log("Bucket exists and we have access");
     }
});

==== Update 2017-02-22 ====

2017-02-22 = = = = = = = =更新

As pointed out in the comment, this is miss-leading. In 2013 I guess it did result in a "folder" being created (as far as the S3 UI is concerned).

正如评论中指出的,这是误导。在2013年,我猜想它确实导致创建了一个“文件夹”(就S3 UI而言)。

If you run the above with the current AWS SDK, it will create an empty object at key "folderInBucketA" in bucket "bucketA". I don't think that is useful to anyone so please disregard this answer.

如果您使用当前的AWS SDK运行上述操作,它将在bucket“bucketA”中键“folderInBucketA”上创建一个空对象。我不认为这对任何人有用,所以请忽略这个答案。

#4


2  

I find that we do not need an explicit directory creation call anymore.

我发现我们不再需要显式的目录创建调用。

Just the following works for me and automatically creates a directory hierarchy as I need.

下面为我工作,并根据需要自动创建目录层次结构。

var userFolder = 'your_bucket_name' + '/' + variable-with-dir-1-name + '/' + variable-with-dir-2-name;
// IMPORTANT : No trailing '/' at the end of the last directory name

AWS.config.region = 'us-east-1';

AWS.config.update({
    accessKeyId: 'YOUR_KEY_HERE',
    secretAccessKey: 'your_secret_access_key_here'
});

var bucket = new AWS.S3({
    params: {
        Bucket: userFolder
    }
});

var contentToPost = {
    Key: <<your_filename_here>>, 
    Body: <<your_file_here>>,
    ContentEncoding: 'base64',
    ContentType: <<your_file_content_type>>,
    ServerSideEncryption: 'AES256'
};

bucket.putObject(contentToPost, function (error, data) {

    if (error) {
        console.log("Error in posting Content [" + error + "]");
        return false;
    } /* end if error */
    else {
        console.log("Successfully posted Content");
    } /* end else error */
})
.on('httpUploadProgress',function (progress) {
    // Log Progress Information
    console.log(Math.round(progress.loaded / progress.total * 100) + '% done');
});

#1


28  

S3 does not have folders or files; it has buckets and objects. Buckets are used to store objects, and objects comprise data (which can be a file) and metadata (information about the data).

S3没有文件夹或文件;它有桶和物体。存储桶用于存储对象,对象包含数据(可以是文件)和元数据(关于数据的信息)。

You don't need to pre-create a folder structure in S3. You can simply put an object with key=cars/ford/sedans/focus.png even if cars/ford/sedans/ does not exist. In this case:

您不需要在S3中预先创建文件夹结构。你可以简单地用key=cars/ford/sedans/focus来放置一个对象。即使汽车/福特/轿车/不存在png。在这种情况下:

  • the putObject call will create an object at cars/ford/sedans/focus.png but it will not create anything representing the intermediate folder structure of cars/ford/sedans/.

    putObject调用将在cars/ford/sedans/focus中创建一个对象。但是它不会创建任何表示汽车/福特/轿车/中间文件夹结构的东西。

  • the actual folder structure does not exist, but is implied through your use of delimiter=/ in your calls to listObjects, and the folders will be returned in CommonPrefixes while the files will be returned in Contents.

    实际的文件夹结构不存在,但通过调用listObjects时使用delimiter=/来表示,文件夹将在CommonPrefixes中返回,而文件将在内容中返回。

  • you will not be able to test for the sedans sub-folder using headObject because cars/ford/sedans/ does not actually exist (it is not an object). Instead you have two options:

    您将无法使用headObject对轿车子文件夹进行测试,因为汽车/福特/轿车/轿车实际上并不存在(它不是一个对象)。相反,你有两个选择:

    • call listObjects with prefix=cars/ford/sedans/ and then find it in Contents, or
    • 调用前缀为=cars/ford/sedans/然后在内容中找到它
    • call listObjects with prefix=cars/ford/, delimiter=/ and then find it in CommonPrefixes.
    • 调用具有前缀=cars/ford/、delimiter=/的listobject,然后在CommonPrefixes中找到它。

It is, however, possible to create an S3 object that represents a folder, if you really want to. To create myfolder in a bucket named mybucket, you can issue a putObject call with bucket=mybucket and key=myfolder/. Note the trailing forward slash. In this case:

但是,如果您确实需要,可以创建一个表示文件夹的S3对象。要在一个名为mybucket的桶中创建myfolder,您可以使用bucket=mybucket和key=myfolder/来发出putObject调用。注意后面的斜线。在这种情况下:

  • the folder is actually a zero-sized object whose key ends in /. Note that if you leave off the trailing / then you will get a zero-sized object that appears to be a file rather than a folder.

    文件夹实际上是一个大小为零的对象,其键以/结尾。请注意,如果您省略了尾随/之后,您将得到一个看起来是文件而不是文件夹的零大小对象。

  • you can test for the presence of myfolder/subfolder/ in mybucket by issuing a headObject call with bucket=mybucket and key=myfolder/subfolder/.

    通过使用bucket和key=myfolder/子文件夹/子文件夹/子文件夹/发出一个headObject调用,可以测试myfolder/子文件夹/在mybucket中的存在性。

Finally, note that your folder delimiter can be anything you like, for example +, because it is simply part of the key and is not actually a folder separator (there are no folders). You can vary your folder delimiter from listObjects call to call if you like.

最后,请注意,您的文件夹分隔符可以是您喜欢的任何东西,例如+,因为它只是键的一部分,实际上并不是一个文件夹分隔符(没有文件夹)。如果您愿意,可以将您的文件夹分隔符从listObjects调用更改为call。

#2


14  

The code from @user2837831 doesn't seem to work anymore, probably with the new version of javascript sdk. So I am adding here the version of code that I am using to create a folder inside a bucket using node.js. This works with the 2.1.31 sdk. What is important is the '/' at the end of the Key value in params - using that it thinks you are trying to create a folder and not a file.

@user2837831的代码似乎不再有用了,可能是新版本的javascript sdk。所以我在这里添加了我用来在bucket中使用node.js创建文件夹的代码版本。这适用于2.1.31 sdk。重要的是params中键值末尾的'/'——使用它会认为您正在创建一个文件夹,而不是一个文件。

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var s3Client = new AWS.S3();

var params = { Bucket: 'your_bucket_goes_here', Key: 'folderInBucket/', ACL: 'public-read', Body:'body does not matter' };

s3Client.upload(params, function (err, data) {
if (err) {
    console.log("Error creating the folder: ", err);
    } else {
    console.log("Successfully created a folder on S3");

    }
});

#3


8  

A folder in a bucket is just another bucket. So you can use headBucket to check if it exists and create it with createBucket if it doesn't. Something like this:

bucket中的文件夹就是另一个bucket。因此,您可以使用headBucket检查它是否存在,如果不存在,可以使用createBucket创建它。是这样的:

var AWS = require('aws-sdk'),
    s3 = new AWS.S3(),
    bucketFolder = 'bucketA/folderInBucketA';

s3.headBucket({Bucket:bucketFolder},function(err,data){
    if(err){
        s3.createBucket({Bucket:bucketFolder},function(err,data){
            if(err){ throw err; }
            console.log("Bucket created");
        });
     } else {
         console.log("Bucket exists and we have access");
     }
});

==== Update 2017-02-22 ====

2017-02-22 = = = = = = = =更新

As pointed out in the comment, this is miss-leading. In 2013 I guess it did result in a "folder" being created (as far as the S3 UI is concerned).

正如评论中指出的,这是误导。在2013年,我猜想它确实导致创建了一个“文件夹”(就S3 UI而言)。

If you run the above with the current AWS SDK, it will create an empty object at key "folderInBucketA" in bucket "bucketA". I don't think that is useful to anyone so please disregard this answer.

如果您使用当前的AWS SDK运行上述操作,它将在bucket“bucketA”中键“folderInBucketA”上创建一个空对象。我不认为这对任何人有用,所以请忽略这个答案。

#4


2  

I find that we do not need an explicit directory creation call anymore.

我发现我们不再需要显式的目录创建调用。

Just the following works for me and automatically creates a directory hierarchy as I need.

下面为我工作,并根据需要自动创建目录层次结构。

var userFolder = 'your_bucket_name' + '/' + variable-with-dir-1-name + '/' + variable-with-dir-2-name;
// IMPORTANT : No trailing '/' at the end of the last directory name

AWS.config.region = 'us-east-1';

AWS.config.update({
    accessKeyId: 'YOUR_KEY_HERE',
    secretAccessKey: 'your_secret_access_key_here'
});

var bucket = new AWS.S3({
    params: {
        Bucket: userFolder
    }
});

var contentToPost = {
    Key: <<your_filename_here>>, 
    Body: <<your_file_here>>,
    ContentEncoding: 'base64',
    ContentType: <<your_file_content_type>>,
    ServerSideEncryption: 'AES256'
};

bucket.putObject(contentToPost, function (error, data) {

    if (error) {
        console.log("Error in posting Content [" + error + "]");
        return false;
    } /* end if error */
    else {
        console.log("Successfully posted Content");
    } /* end else error */
})
.on('httpUploadProgress',function (progress) {
    // Log Progress Information
    console.log(Math.round(progress.loaded / progress.total * 100) + '% done');
});