Зачем добавлять, а не писать при использовании knox / node.js для получения файла из Amazon s3 - PullRequest
0 голосов
/ 04 февраля 2012

Я экспериментирую с модулем knox для node.js для управления некоторыми небольшими файлами в корзине Amazon S3. Все работает автономно: я могу загрузить файл, загрузить файл и т. Д. Однако я хочу иметь возможность загружать файл по расписанию. Когда я изменяю код, чтобы он выполнялся с интервалом, я получаю загруженный файл, добавляя к предыдущему экземпляру вместо перезаписи.

Я не уверен, что допустил ошибку в коде записи файла или в коде обработки 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);

1 Ответ

1 голос
/ 04 февраля 2012

Проблема с вашим размещением var downTxt = '';. Это единственное место, где вы устанавливаете значение downTxt пустым, поэтому каждый раз, когда вы извлекаете больше данных, вы добавляете их к данным, полученным в предыдущем запросе, потому что вы никогда не очищаете данные из предыдущего запроса. Самое простое решение - переместить эту строку непосредственно перед строкой setEncoding.

Однако способ обработки данных неоправданно сложен. Попробуйте что-то вроде этого. Вам не нужно каждый раз заново создавать клиент, а установка кодировки просто сломает вещи, если вы загружаете нетекстовые файлы, и не будет иметь значения для текстовых файлов. Далее, вам не нужно вручную собирать данные, вы можете сразу же начать записывать их в файл по мере их получения. Наконец, поскольку запрос является стандартным потоком, вам не нужно отслеживать событие «data», потому что вы можете просто использовать 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);
  });
})();
...