我对NodeJS流有点新鲜,我越了解它,我越相信它不是一个 特别简单稳定的东西。我试图用大字写文件 csv / csv-parse(显然是最受欢迎的CSV模块 与NodeJS)使用piping API,其中 涉及使用同一作者的stream-transform。
我在这里遇到的部分内容实际上是可以重现的,而不是实际使用解析器,所以 我对这些部分进行了评论,以使示例更简单(对于那些喜欢JavaScript而不是CoffeeScript的人, there's also a JS version):
#-------------------------------------------------------------------------------
fs = require 'fs'
transform_stream = require 'stream-transform'
log = console.log
as_transformer = ( method ) -> transform_stream method, parallel: 11
# _new_csv_parser = require 'csv-parse'
# new_csv_parser = -> _new_csv_parser delimiter: ','
#-------------------------------------------------------------------------------
$count = ( input_stream, title ) ->
count = 0
#.............................................................................
input_stream.on 'end', ->
log ( title ? 'Count' ) + ':', count
#.............................................................................
return as_transformer ( record, handler ) =>
count += 1
handler null, record
#-------------------------------------------------------------------------------
read_trips = ( route, handler ) ->
# parser = new_csv_parser()
input = fs.createReadStream route
#.............................................................................
input.on 'end', ->
log 'ok: trips'
return handler null
input.setMaxListeners 100 # <<<<<<
#.............................................................................
# input.pipe parser
input.pipe $count input, 'trips A'
.pipe $count input, 'trips B'
.pipe $count input, 'trips C'
.pipe $count input, 'trips D'
# ... and so on ...
.pipe $count input, 'trips Z'
#.............................................................................
return null
route = '/Volumes/Storage/cnd/node_modules/timetable-data/germany-berlin-2014/trips.txt'
read_trips route, ( error ) ->
throw error if error?
log 'ok'
输入文件包含204865行GTFS数据; 我没有在这里解析它,只是原始阅读,所以我想我用上面的代码计算的是块 数据。
我将流从柜台输送到柜台,并且预计会经常到达最后一个柜台 第一个;然而,这就是我得到的:
trips A: 157
trips B: 157
trips C: 157
...
trips U: 157
trips V: 144
trips W: 112
trips X: 80
trips Y: 48
trips Z: 16
在早期的设置中我实际上解析了数据,我得到了这个:
trips A: 204865
trips B: 204865
trips C: 204865
...
trips T: 204865
trips U: 180224
trips V: 147456
trips W: 114688
trips X: 81920
trips Y: 49152
trips Z: 16384
所以看起来这条小溪在某种程度上是干涸的。
我怀疑输入流的end
事件不是一个可靠的信号来收听
试图决定是否所有处理都已完成 - 毕竟,假设处理是合乎逻辑的
只有完成消耗之后才能完成一段时间。
所以我寻找另一个事件来听(没找到一个)并延迟调用回调(用
setTimeout
,process.nextTick
和setImmediate
),但无济于事。
如果有人能指出
那就太好了setTimeout
,process.nextTick
和setImmediate
之间的重要差异在此背景下, 更新我现在认为问题在于流变换有一个问题,有人报告一个非常相似的问题与几乎相同的数字(他有234841记录,最终得到16390,我有204865并以16384结束。不是证据,而是过于接近偶然。
我抛弃了流转换并改为使用event-stream.map;测试然后运行正常。
答案 0 :(得分:2)
几天后,我想我可以说stream-transform存在大文件问题。
我已经切换到event-stream这是恕我直言总体上更好的解决方案,因为它是完全通用的(即它通常是关于流,而不是特别是关于CSV数据的流)。我已经在我的初始pipdreams模块的文档中概述了有关NodeJS中的流库的一些想法,该模块提供了许多常用的流操作。