【问题标题】:Listing all the directories and all the files and uploading them to my bucket (S3 Amazon) with Node.JS列出所有目录和所有文件,并使用 Node.JS 将它们上传到我的存储桶(S3 Amazon)
【发布时间】:2026-01-26 02:00:01
【问题描述】:

代码如下:

我正在使用 findit walker,文档在这里 -> https://github.com/substack/node-findit

通过这个包,我列出了我的应用程序的所有目录和文件,并且我试图发送到我在 Amazon S3 上的存储桶(使用我自己的代码)。

我不确定代码是否正确,也不知道需要在 Body 中的 params 对象中添加什么。

这部分正在监听我应用的所有目录:

finder.on('directory', function (dir, stat, stop) {
    var base = path.basename(dir);
    if (base === '.git' || base === 'node_modules' || base === 'bower_components') {
        stop();
    }
    else {
        console.log(dir + '/');
    }
});

而这个正在监听我的应用程序的所有文件:

finder.on('file', function (file, stat) {
  console.log(file);
});

我更新了它以将数据发送到我的存储桶,如下所示:

finder.on('file', function (file, stat) {
    console.log(file);
    var params = {
        Bucket: BUCKET_NAME,
        Key: file,
        //Body:
    };
    //console.log(params.body);


    s3.putObject(params, function(err) {
        if(err) {
            console.log(err);
        }
        else {
            console.log("Success!");
        }
    });
});

我真的不知道我需要在 Body 中放什么,也不知道代码是否正确。谁能帮帮我?

谢谢。

帮助,所有代码,所有代码:

var fs = require('fs');
var finder = require('findit')(process.argv[2] || '.');
var path = require('path');
var aws = require('aws-sdk');

var s3 = new aws.S3();
aws.config.loadFromPath('./AwsConfig.json');
var BUCKET_NAME = 'test-dev-2';



finder.on('directory', function (dir, stat, stop) {
    var base = path.basename(dir);
    if (base === '.git' || base === 'node_modules' || base === 'bower_components') {
        stop();
    }
    else {
        console.log(dir + '/');
    }
});

finder.on('file', function (file, stat) {
    console.log(file);
    var params = {
        Bucket: BUCKET_NAME,
        Key: file,
        //Body:
    };
    //console.log(params.body);


    s3.putObject(params, function(err) {
        if(err) {
            console.log(err);
        }
        else {
            console.log("Success");
        }
    });
});

finder.on('error', function (err) {
    console.log(err);
});

finder.on('end', function () {
    console.log('Done!');
});

【问题讨论】:

  • 请将代码的相关部分直接复制并粘贴到问题中,而不是发布它的图像。我们不能对图像做太多事情。
  • 对不起,我认为整个代码的图片会更好,只需第二个@MikeS。
  • 没问题。人们通常会复制您的部分或全部代码并尝试重现问题以确定您的问题的最佳答案是什么。一张图片可不容易:)
  • 我觉得现在看起来好多了@MikeS :D
  • 这样好多了:)

标签: node.js amazon-web-services amazon-s3


【解决方案1】:

基于documentations3.putObjectBody 参数可以采用Buffer、Typed Array、Blob、StringReadableStream。在大多数情况下,最好使用的是ReadableString。您可以使用fs 模块中的createReadStream() function 从任何文件创建ReadableString

因此,您的代码部分看起来像:

finder.on('file', function (file, stat) {
    console.log(file);
    var params = {
        Bucket: BUCKET_NAME,
        Key: file,
        Body: fs.createReadStream(file) // NOTE: You might need to adjust "file" so that it's either an absolute path, or relative to your code's directory.
    };

    s3.putObject(params, function(err) {
        if(err) {
            console.log(err);
        }
        else {
            console.log("Success!");
        }
    });
});

我还想指出,如果您将包含大量文件的目录传递给此代码,您可能会遇到问题。 putObject 是一个 asynchronous 函数,这意味着它会被调用,然后代码会在它做它的时候转移到其他东西(好吧,这是一个非常简单的,但你可以想到那样)。就这段代码而言,这意味着您实际上将同时上传它找到的所有文件;这不好。

我的建议是使用async modulequeue 之类的文件上传文件,这样一次只发生其中的几个。

基本上,您会将 file 事件处理程序中的代码移动到队列的工作方法中,如下所示:

var async = require('async');

var uploadQueue = async.queue(function(file, callback) {
    var params = {
        Bucket: BUCKET_NAME,
        Key: file,
        Body: fs.createReadStream(file) // NOTE: You might need to adjust "file" so that it's either an absolute path, or relative to your code's directory.
    };

    s3.putObject(params, function(err) {
        if(err) {
            console.log(err);
        }
        else {
            console.log("Success!");
        }

        callback(err); // <-- Don't forget the callback call here so that the queue knows this item is done
    });
}, 2); // <-- This "2" is the maximum number of files to upload at once

注意最后的2,它指定了你的并发,在这种情况下,是一次上传多少个文件。

然后,您的 file 事件处理程序就变成了:

finder.on('file', function (file, stat) {
    uploadQueue.push(file);
});

这会将它找到的所有文件排队并一次上传 2 个,直到它通过所有文件。

【讨论】:

  • 不,刚刚做了一段时间;)
  • Hei Mike,push 是如何使用的?我知道推送方法只是为了加入数组......哈哈.. 更新:没关系,我现在明白了哈哈
  • 日复一日,目前还没有那么多(更专注于 iOS 开发),但自 2011 年中期以来,我已经在 node 中编写了很多 Web 应用程序和实用程序。如果这是您在 3 个月后所处的位置,那么您做得很好:) 至于 push,它只是在这种情况下使用的函数名称 async(它与数组上的 push 不同)。之所以这样命名,是因为事情通常被“推送”到队列中(并“弹出”)。
【解决方案2】:

一个更简单且可以说更有效的解决方案可能是对目录进行 tar 并上传单个 tar 文件(如果需要,也可以压缩)。 npm 上有 tar 模块,但你也可以为它生成一个子进程。

【讨论】:

    最近更新 更多