使用knox/node.js从Amazons3抓取文件时,为什么要附加而不是写入



我正在试验node.js的knox模块,作为管理AmazonS3存储桶中一些小文件的一种方式。独立运行一切都很好:我可以上传文件、下载文件等。但是,我希望能够定期下载文件。当我修改代码以在间隔内运行时,我会将下载的文件附加到上一个实例,而不是覆盖。

我不确定我是在文件编写代码还是在knox处理代码中犯了错误。我尝试了几种不同的编写方法(writeFile、writeStream等),并查看了knox源代码。对我来说没有什么明显的问题。这是我正在使用的代码:

knox = require('knox');
fs = require('fs');
var downFile = DOWNFILE;
var downTxt = '';
var timer = INTERVAL;
var path = S3PATH + downFile;
setInterval(function() 
{
        var s3client = knox.createClient(
        {
                key: '********************',
                secret: '**********************************',
                bucket: '********'
        });
        s3client.get(path).on('response', function(response)
        {
                response.setEncoding('ascii');
                response.on('data', function(chunk)
                {
                        downTxt += chunk;
                });
                response.on('end', function()
                {
                        fs.writeFileSync(downFile, downTxt, 'ascii');
                });
        }).end();
},
timer);

问题出在var downTxt = '';的位置上。这是您将downTxt设置为空白的唯一位置,因此每次检索更多数据时,都会将其添加到上一个请求中获得的数据中,因为您从未清除上一个申请中的数据。最简单的修复方法是将该行移动到setEncoding行之前。

然而,您处理数据的方式是不必要的复杂。不如试试这样的。你不需要每次都重新创建客户端,如果你下载的是非文本文件,设置编码只会破坏一切,而文本文件也不会有什么不同。接下来,你不应该手动收集数据,你可以在收到数据后立即开始将其写入文件。最后,由于请求是标准流,你不需要监控"数据"事件,因为你只需要使用pipe

var knox = require('knox'),
    fs = require('fs'),
    downFile = DOWNFILE,
    timer = INTERVAL,
    path = S3PATH + downFile,
    s3client = knox.createClient({
        key: '********************',
        secret: '**********************************',
        bucket: '********'
    });
(function downloadFile() {
  var str = fs.createWriteStream(downFile);
  s3client.get(path).pipe(str);
  str.on('close', function() {
    setTimeout(downloadFile, timer);
  });
})();

最新更新