gpt4 book ai didi

javascript - 如何处理大文件、NodeJS 流和管道

转载 作者:搜寻专家 更新时间:2023-10-31 23:54:41 24 4
gpt4 key购买 nike

我对 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数据;我不是在这里解析它,只是阅读它,所以我猜我用上面的代码计算的是 block 的数据。

我正在从一个柜台流到另一个柜台,并希望尽可能多地到达最后一个柜台第一个;然而,这就是我得到的:

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 事件不是一个可靠的信号试图决定是否所有处理都已完成——毕竟,假设处理是合乎逻辑的只能在流完全消耗完后的一段时间内完成。

所以我寻找另一个事件来监听(没有找到)并延迟调用回调(与 setTimeoutprocess.nextTicksetImmediate ),但无济于事。

如果有人能指出来就好了

  • (1) setTimeoutprocess.nextTicksetImmediate 之间的关键区别是什么,以及
  • (2) 如何可靠地判断最后一个字节是否已经被管道的最后一个成员处理。

更新 我现在认为问题在于流转换,它有一个 Unresolved 问题,有人用几乎相同的数字报告了一个非常相似的问题(他有 234841 条记录,最后是 16390,我有204865 并以 16384 结束)。不是证明,但太接近了,不可能是偶然的。

我放弃了流转换并改用 event-stream.map;然后测试运行正常。

最佳答案

几天后我想我可以说了stream-transform大文件有问题。

我已经切换到 event-stream恕我直言,这是一个更好的整体解决方案,因为它是完全通用的(即它是关于一般的流,而不是特别关于 CSV-data-as-streams)。我在我的早期文档中概述了一些关于 NodeJS 中的流库的想法 pipdreams模块,提供了一些常用的流操作。

关于javascript - 如何处理大文件、NodeJS 流和管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25181441/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com