2016-04-14 163 views
0

我试图通过执行以下操作来提取csv文件图片:使用csv-parsefscreateReadStream方法createWriteStream“关闭”事件未触发

  1. 解析/流在一个大的csv文件
  2. 抓取每行使用stream-transform
  3. 提取图像和其他行数据以使用async瀑布方法进行处理。
  4. 下载和数据被管道输送到createWriteStream后编写使用requestfscreateWriteStream方法

出于某种原因,图像服务器,有一些事件,其中async回调不会被调用。我已经运行相同的代码只使用request,没有管道到createWriteStream,它的工作原理。我也运行createWriteStream w/a drain事件,然后一些它是如何工作的?任何人都可以向我解释这个吗?

在下面的代码,request试图管14970张的图像,但是createWriteStreamclosefinish事件只火14,895次,error射击0次。这可能是一个枯竭的问题?可能会超过highWaterMark,写入失败可能未被发现?

这里是我的CSV行获得代码:

var first = true; 
var parser = parse(); 
var transformer = transform((line, complete) => { 
     if(!first) 
      extractData(line,complete) 
     else { 
      first = false; 
      complete(null); 
     } 
    }, 
    () => { 
     console.log('Done: parseFile'); 
    }); 
fs.createReadStream(this.upload.location).pipe(parser).pipe(transformer); 

extractData函数并不总是做一个需要async回调:

extractData(line,complete){ 
    var now = new Date(); 
    var image = { 
     createdAt: now, 
     updatedAt: now 
    }; 
    async.waterfall([ 
     next => { // Data Extraction 
      async.forEachOf(line, (data, i, complete) => { 
       if(i === 2) image.src = data; 
       if(i === 3) image.importSrc = data; 
       complete(null); 
      }, err => { 
       if(err) throw err; 
       next(null); 
      }); 
     }, 
     next => { // Download Image 
      var file = fs.createWriteStream('public/'+image.src); 
      var sendReq = request.get(image.importSrc); 
      sendReq.on('response', response => { 
       if (response.statusCode !== 200) { 
        this.upload.report.image.errors++; 
        return next(null); 
       } 
      }); 
      sendReq.on('error', err => { 
       this.upload.report.image.errors++; 
       next(null); 
      }); 
      sendReq.pipe(file); 
      file.on('finish',() => { 
       this.upload.report.image.inserts++; 
       file.close(next); // Close file and callback 
      }); 
      file.on('error', err => { 
       this.upload.report.image.errors++; 
       next(null); 
      }); 
     } 
    ], err => { 
     if(err) throw err; 
     complete(null); 
    }); 
} 

正如@mscdex建议,我也试着换掉finish替代他的替换close的做法。

回答

0

file.close(next);是不必要的,因为文件流默认是自动关闭的。你可以做的是听取close事件,以了解流的文件描述符何时已关闭。所以更换整个finish事件处理程序:

file.on('close',() => { 
    this.upload.report.image.inserts++; 
    next(null); 
}); 
+0

我给它一个去,让你知道它的工作 – user1828780

+0

我尝试了上面,并没有奏效。它试图下载和请求14,970张图像,但“close”仅被称为14,895次。 '错误'被称为0次。 – user1828780