是的,我知道。 s3存储上没有文件夹概念。但我真的想用node.js从s3中删除一个特定的文件夹。我尝试了两种解决方案,但都没有用。 我的代码如下: 解决方案1: 直接删除文件夹。
var key='level/folder1/folder2/';
var strReturn;
var params = {Bucket: MyBucket};
var s3 = new AWS.S3(params);
s3.client.listObjects({
Bucket: MyBucket,
Key: key
}, function (err, data) {
if(err){
strReturn="{\"status\":\"1\"}";
}else{
strReturn=+"{\"status\":\"0\"}";
}
res.send(returnJson);
console.log('error:'+err+' data:'+JSON.stringify(data));
});
实际上,我在folder2下有很多文件。如果我像这样定义键,我可以从folder2删除单个文件: var key ='level / folder1 / folder2 / file1.txt',但是当我删除文件夹(key ='level / folder1 / folder2 /')时它不起作用。 解决方案2: 当我将此文件或文件夹上传到s3时,我尝试将对期设置为对象。代码如下:
s3.client.putObject({
Bucket: Camera_Bucket,
Key: key,
ACL:'public-read',
Expires: 60
}
但它也没有。完成上传后,我检查了该文件的属性。它表明到期日没有任何价值:
Expiry Date:none
Expiration Rule:N/A
如何使用node.js删除s3上的文件夹?
答案 0 :(得分:49)
您可以使用aws-sdk模块删除文件夹。因为你可以在文件夹为空时删除它,你应该删除其中的文件。我是这样做的。
function emptyBucket(bucketName,callback){
var params = {
Bucket: bucketName,
Prefix: 'folder/'
};
s3.listObjects(params, function(err, data) {
if (err) return callback(err);
if (data.Contents.length == 0) callback();
params = {Bucket: bucketName};
params.Delete = {Objects:[]};
data.Contents.forEach(function(content) {
params.Delete.Objects.push({Key: content.Key});
});
s3.deleteObjects(params, function(err, data) {
if (err) return callback(err);
if(data.Contents.length == 1000)emptyBucket(bucketName,callback);
else callback();
});
});
}
答案 1 :(得分:21)
以下是ES7中使用test:
services:
- name: rest-server
id: edh/rest-server
cmd: java -jar /path/to/my-code.jar
steps:
- java/maven:
goals: verify
maven_opts: -DrestEndpoint=http://rest-server:9000
函数并使用async
(修订后的List Objects API)的实现:
listObjectsV2
要打电话:
async function emptyS3Directory(bucket, dir) {
const listParams = {
Bucket: bucket,
Prefix: dir
};
const listedObjects = await s3.listObjectsV2(listParams).promise();
if (listedObjects.Contents.length === 0) return;
const deleteParams = {
Bucket: bucket,
Delete: { Objects: [] }
};
listedObjects.Contents.forEach(({ Key }) => {
deleteParams.Delete.Objects.push({ Key });
});
await s3.deleteObjects(deleteParams).promise();
if (listedObjects.IsTruncated) await emptyS3Directory(bucket, dir);
}
答案 2 :(得分:1)
listObjectsV2 仅列出带有当前目录前缀而不带有子文件夹前缀的文件。如果要递归删除包含子文件夹的文件夹,这是源代码:https://github.com/tagspaces/tagspaces/blob/develop/app/services/objectstore-io.ts#L838
deleteDirectoryPromise = async (path: string): Promise<Object> => {
const prefixes = await this.getDirectoryPrefixes(path);
if (prefixes.length > 0) {
const deleteParams = {
Bucket: this.config.bucketName,
Delete: { Objects: prefixes }
};
return this.objectStore.deleteObjects(deleteParams).promise();
}
return this.objectStore
.deleteObject({
Bucket: this.config.bucketName,
Key: path
})
.promise();
};
/**
* get recursively all aws directory prefixes
* @param path
*/
getDirectoryPrefixes = async (path: string): Promise<any[]> => {
const prefixes = [];
const promises = [];
const listParams = {
Bucket: this.config.bucketName,
Prefix: path,
Delimiter: '/'
};
const listedObjects = await this.objectStore
.listObjectsV2(listParams)
.promise();
if (
listedObjects.Contents.length > 0 ||
listedObjects.CommonPrefixes.length > 0
) {
listedObjects.Contents.forEach(({ Key }) => {
prefixes.push({ Key });
});
listedObjects.CommonPrefixes.forEach(({ Prefix }) => {
prefixes.push({ Key: Prefix });
promises.push(this.getDirectoryPrefixes(Prefix));
});
// if (listedObjects.IsTruncated) await this.deleteDirectoryPromise(path);
}
const subPrefixes = await Promise.all(promises);
subPrefixes.map(arrPrefixes => {
arrPrefixes.map(prefix => {
prefixes.push(prefix);
});
});
return prefixes;
};
答案 3 :(得分:0)
根据接受的答案,我创建了promise返回函数,因此您可以将其链接。
function emptyBucket(bucketName){
let currentData;
let params = {
Bucket: bucketName,
Prefix: 'folder/'
};
return S3.listObjects(params).promise().then(data => {
if (data.Contents.length === 0) {
throw new Error('List of objects empty.');
}
currentData = data;
params = {Bucket: bucketName};
params.Delete = {Objects:[]};
currentData.Contents.forEach(content => {
params.Delete.Objects.push({Key: content.Key});
});
return S3.deleteObjects(params).promise();
}).then(() => {
if (currentData.Contents.length === 1000) {
emptyBucket(bucketName, callback);
} else {
return true;
}
});
}
答案 4 :(得分:0)
根据Emi的回答,我制作了一个npm软件包,因此您不会 无需自己编写代码。代码也是用打字稿写的。
请参见https://github.com/bingtimren/s3-commons/blob/master/src/lib/deleteRecursive.ts
答案 5 :(得分:0)
您可以使用删除文件的相同方式删除空文件夹。为了删除AWS S3上的非空文件夹,您需要先通过删除其中的所有文件和文件夹将其清空。文件夹为空后,您可以将其作为常规文件删除。桶删除也一样。我们已经在名为Commandeer的此应用中实现了它,因此您可以通过GUI来实现。
答案 6 :(得分:0)
您可以尝试以下方法:
import { s3DeleteDir } from '@zvs001/s3-utils'
import { S3 } from 'aws-sdk'
const s3Client = new S3()
await s3DeleteDir(s3Client, {
Bucket: 'my-bucket',
Prefix: `folder/`,
})
答案 7 :(得分:0)
在打字稿中使用时,接受的答案会引发错误,并且它是 deleteParams 中的对象数组。我通过以下方式修改代码使其工作。我对 Typescript 很陌生,但至少现在可以使用了。
async function emptyS3Directory(prefix: string) {
const listParams = {
Bucket: "bucketName",
Prefix: prefix, // ex. path/to/folder
};
const listedObjects = await s3.listObjectsV2(listParams).promise();
if (listedObjects.Contents.length === 0) return;
const deleteParams = {
Bucket: bucketName,
Delete: { Objects: [] as any },
};
listedObjects.Contents.forEach((content: any) => {
deleteParams.Delete.Objects.push({ Key: content.Key });
});
await s3.deleteObjects(deleteParams).promise();
if (listedObjects.IsTruncated) await emptyS3Directory(prefix);
}