【问题标题】:NodeJS - file does not exist after piping to writeStream and awaiting finish eventNodeJS - 在管道到 writeStream 并等待完成事件后文件不存在
【发布时间】:2018-01-20 13:13:44
【问题描述】:

我正在使用以下代码尝试通过 HTTP 下载文件。我正在尝试使用流,因为文件很大。我遇到的问题是,在我通过管道将响应发送到创建的 WritableStream 后,有时文件没有创建,因此代码稍后会在检查校验和时出错。

换句话说,即使文件不存在/尚未创建,WritableStream 的“完成”事件也会触发。

exports.downloadHttpFile = function(url, path, mimeType, checksum) {
    return exports.get(url, mimeType, false).then(function(res) {
        if (res.statusCode != 200) {
            return Promise.reject(new Error('Invalid response from server when trying to download file'))
        } else {
            return new Promise(function(resolve, reject) {
                console.log('creating file at ' + path)
                const writable = fs.createWriteStream(path);

                writable.once('open', () => res.pipe(writable).once('error', reject)).on('finish', function() {
                    writable.end();
                    try {
                        if (checksum) {
                            console.log(checksum)
                            if (!checksum.hashType || !checksum.hashEncoding || !checksum.hashValue) return reject(new Error('Invalid checksum object'))

                            fs.createReadStream(path)
                                .once('error', function() {
                                    console.log('ERRORS OUT HERE, FILE NO EXIST (path not created by fs.createWriteStream)')
                                })
                                .pipe(require('crypto').createHash(checksum.hashType).setEncoding(checksum.hashEncoding))
                                .once('finish', function() {
                                    const fileHash = this.read();
                                    if (fileHash != checksum.hashValue) {
                                        try {
                                            fs.unlinkSync(path);
                                        } catch (err) {}
                                        return reject(new Error('Downladed file checksum did not match given checksum'));
                                    } else {
                                        return resolve(path);
                                    }
                                }).once('error', reject)
                        } else {
                            return resolve(path);
                        }
                    } catch (err) {
                        console.log('File did not exist after piping to writable stream..')
                        return reject(err);
                    }
                }).once('error', reject);
            });
        }
    })
}

谁能告诉我哪里出错了?谢谢

【问题讨论】:

    标签: javascript file stream


    【解决方案1】:

    我设法通过检查文件是否存在以及它是否不调用 downloadHttpFile 来解决此问题。我知道这不是一个很好的解决方案,我不确定为什么它在文件尚未创建时触发完成事件..但它现在会做,除非有人有更好的解决方案。

    代码如下:

    exports.downloadHttpFile = function (url, path, mimeType, checksum) {
      return exports.get(url, mimeType, false).then(function (res) {
        if (res.statusCode != 200) {
          return Promise.reject(new Error('Invalid response from server when trying to download file'))
        } else {
          return new Promise(function (resolve, reject) {
            const writable = fs.createWriteStream(path)
    
            writable.on('finish', function () {
              let pathExists = false
              try {
                fs.statSync(path)
                pathExists = true
              } catch (err) {}
    
              if (pathExists) {
                if (checksum) {
                  console.log(checksum)
                  if (!checksum.hashType || !checksum.hashEncoding || !checksum.hashValue) return reject(new Error('Invalid checksum object'))
    
                  console.log('creating read stream for path ' + path)
                  fs.createReadStream(path)
                    .pipe(require('crypto').createHash(checksum.hashType).setEncoding(checksum.hashEncoding).once('error', function (err) {
                      console.log('Error creating crc code')
                      return reject(err)
                    }))
                    .once('finish', function () {
                      console.log('Finished reading stream')
                      const fileHash = this.read()
                      if (fileHash != checksum.hashValue) {
                        console.log('Checksums did not match')
                        console.log(fileHash)
                        console.log(checksum.hashValue)
                        return reject(new Error('Downladed file checksum did not match given checksum'))
                      } else {
                        console.log('Checksums matched')
                        return resolve(path)
                      }
                    }).once('error', reject)
                } else {
                  return resolve(path)
                }
              } else {
                console.log('File did not exist.. attempting to redownload' + path)
                return resolve(exports.downloadHttpFile(url, path, mimeType, checksum))
              }
            }).on('error', function (err) {
              console.log(err)
              return reject(err)
            })
    
            res.pipe(writable).on('error', function (err) {
              console.log('Error reading response')
              return reject(err)
            })
          })
        }
      })
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-20
      • 2015-12-14
      • 2015-09-27
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多