我从http函数下载了一个简单的下载(为简化省略了错误处理):
function download(url, tempFilepath, filepath, callback) {
    var tempFile = fs.createWriteStream(tempFilepath);
    http.request(url, function(res) {
        res.on('data', function(chunk) {
            tempFile.write(chunk);
        }).on('end', function() {
            tempFile.end();
            fs.renameSync(tempFile.path, filepath);
            return callback(filepath);
        })
    });
}
但是,由于我download()异步调用了几十次,它很少报告fs.renameSync抱怨它无法找到文件的错误tempFile.path.
Error: ENOENT, no such file or directory 'xxx'
我使用相同的网址列表来测试它,它失败了大约30%的时间.逐个下载时,网址列表相同.
测试了一些,我发现了以下代码
fs.createWriteStream('anypath');
console.log(fs.exist('anypath'));
console.log(fs.exist('anypath'));
console.log(fs.exist('anypath'));
并不总是打印true,但有时打印第一个答案false.
我怀疑太多异步fs.createWriteStream调用无法保证文件创建.这是真的?有没有什么方法可以保证文件的创建?
Joh*_*yHK 63
write在您从流中tempFile收到'open'事件之前,不应该调用您的写入流.在您看到该事件之前,该文件将不存在.
为了你的功能:
function download(url, tempFilepath, filepath, callback) {
    var tempFile = fs.createWriteStream(tempFilepath);
    tempFile.on('open', function(fd) {
        http.request(url, function(res) {
            res.on('data', function(chunk) {
                tempFile.write(chunk);
            }).on('end', function() {
                tempFile.end();
                fs.renameSync(tempFile.path, filepath);
                return callback(filepath);
            });
        });
    });
}
为了您的测试:
var ws = fs.createWriteStream('anypath');
ws.on('open', function(fd) {
    console.log(fs.existsSync('anypath'));
    console.log(fs.existsSync('anypath'));
    console.log(fs.existsSync('anypath'));
});
Dan*_*mov 14
接受的答案没有为我下载一些最后的字节.
这是一个正常工作的Q版本(但没有临时文件).
'use strict';
var fs = require('fs'),
    http = require('http'),
    path = require('path'),
    Q = require('q');
function download(url, filepath) {
  var fileStream = fs.createWriteStream(filepath),
      deferred = Q.defer();
  fileStream.on('open', function () {
    http.get(url, function (res) {
      res.on('error', function (err) {
        deferred.reject(err);
      });
      res.pipe(fileStream);
    });
  }).on('error', function (err) {
    deferred.reject(err);
  }).on('finish', function () {
    deferred.resolve(filepath);
  });
  return deferred.promise;
}
module.exports = {
  'download': download
};
注意我正在收听finish文件流而不是end响应.
| 归档时间: | 
 | 
| 查看次数: | 70065 次 | 
| 最近记录: |