如何使用 NeoJSON 解析 Pharo 中的 ndjson
How to parse ndjson in Pharo with NeoJSON
我想在 Pharo Smalltalk 上解析 ndjson (newline delimited json) data with NeoJSON。
ndjson 数据如下所示:
{"smalltalk": "cool"}
{"pharo": "cooler"}
目前我将我的文件流转换为字符串,在换行符上将其拆分,然后使用 NeoJSON 解析单个部分。这似乎使用了不必要的(而且非常大的)内存和时间,可能是因为一直将流转换为字符串,反之亦然。执行此任务的有效方法是什么?
如果您查找示例数据:NYPL-publicdomain: pd_items_1.ndjson
如果您打开一个新的 ReadWriteStream,首先在上面写入 ${,然后将原始流的所有内容以逗号分隔,然后在其上写入结尾的 $},这是否可行?生成的流应该对 NeoJSON 有好处......?
这可能是对问题的 STTCPW 攻击,但是 W 很重要 ;-) 而且它应该更快并且消耗更少的内存,因为 NeoJSON 只会做一次..
只是一个想法,还没试过。
您可以尝试这样的操作:
| input reader |
input := FileStream readOnlyFileNamed: 'resources/pd_items_1.ndjson.txt'.
[
Array
streamContents: [ :strm |
| ln |
[ (ln := input nextLine) isNil ]
whileFalse: [ strm nextPut: (NeoJSONReader fromString: ln) ] ] ] timeToRun.
除非这是您已经尝试过的...
这是 Sven(NeoJSON 的作者)在 pharo-users 邮件列表(他不在 SO 上)的回答:
阅读 'format' 很容易,只需继续为每个 JSON 表达式执行#next(忽略空格)。
| data reader |
data := '{"smalltalk": "cool"}
{"pharo": "cooler"}'.
reader := NeoJSONReader on: data readStream.
Array streamContents: [ :out |
[ reader atEnd ] whileFalse: [ out nextPut: reader next ] ].
防止中间数据结构也很容易,使用流。
| client reader data networkStream |
(client := ZnClient new)
streaming: true;
url: 'https://github.com/NYPL-publicdomain/data-and-utilities/blob/master/items/pd_items_1.ndjson?raw=true';
get.
networkStream := ZnCharacterReadStream on: client contents.
reader := NeoJSONReader on: networkStream.
data := Array streamContents: [ :out |
[ reader atEnd ] whileFalse: [ out nextPut: reader next ] ].
client close.
data.
花了几秒钟,毕竟 50K 项在网络上是 80MB+。
我想在 Pharo Smalltalk 上解析 ndjson (newline delimited json) data with NeoJSON。
ndjson 数据如下所示:
{"smalltalk": "cool"}
{"pharo": "cooler"}
目前我将我的文件流转换为字符串,在换行符上将其拆分,然后使用 NeoJSON 解析单个部分。这似乎使用了不必要的(而且非常大的)内存和时间,可能是因为一直将流转换为字符串,反之亦然。执行此任务的有效方法是什么?
如果您查找示例数据:NYPL-publicdomain: pd_items_1.ndjson
如果您打开一个新的 ReadWriteStream,首先在上面写入 ${,然后将原始流的所有内容以逗号分隔,然后在其上写入结尾的 $},这是否可行?生成的流应该对 NeoJSON 有好处......? 这可能是对问题的 STTCPW 攻击,但是 W 很重要 ;-) 而且它应该更快并且消耗更少的内存,因为 NeoJSON 只会做一次..
只是一个想法,还没试过。
您可以尝试这样的操作:
| input reader |
input := FileStream readOnlyFileNamed: 'resources/pd_items_1.ndjson.txt'.
[
Array
streamContents: [ :strm |
| ln |
[ (ln := input nextLine) isNil ]
whileFalse: [ strm nextPut: (NeoJSONReader fromString: ln) ] ] ] timeToRun.
除非这是您已经尝试过的...
这是 Sven(NeoJSON 的作者)在 pharo-users 邮件列表(他不在 SO 上)的回答:
阅读 'format' 很容易,只需继续为每个 JSON 表达式执行#next(忽略空格)。
| data reader |
data := '{"smalltalk": "cool"}
{"pharo": "cooler"}'.
reader := NeoJSONReader on: data readStream.
Array streamContents: [ :out |
[ reader atEnd ] whileFalse: [ out nextPut: reader next ] ].
防止中间数据结构也很容易,使用流。
| client reader data networkStream |
(client := ZnClient new)
streaming: true;
url: 'https://github.com/NYPL-publicdomain/data-and-utilities/blob/master/items/pd_items_1.ndjson?raw=true';
get.
networkStream := ZnCharacterReadStream on: client contents.
reader := NeoJSONReader on: networkStream.
data := Array streamContents: [ :out |
[ reader atEnd ] whileFalse: [ out nextPut: reader next ] ].
client close.
data.
花了几秒钟,毕竟 50K 项在网络上是 80MB+。