1

我想在 Pharo Smalltalk 上使用NeoJSON解析ndjson(换行符分隔的 json)数据。

ndjson 数据如下所示:

{"smalltalk": "cool"}
{"pharo": "cooler"}

目前,我将文件流转换为字符串,将其拆分为换行符,然后使用 NeoJSON 解析单个部分。这似乎使用了不必要的(并且非常巨大的)内存和时间,可能是因为一直将流转换为字符串,反之亦然。什么是完成这项任务的有效方法?

如果您查找示例数据:NYPL-publicdomain: pd_items_1.ndjson

4

3 回答 3

3

这是 Sven(NeoJSON 的作者)在 pharo-users 邮件列表中的回答(他不在 SO 上):

阅读“格式”很容易,只需继续为每个 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+。

于 2016-01-21T12:52:24.837 回答
2

如果您打开一个新的 ReadWriteStream,首先在其上写入 ${,然后将原始流的所有内容(以逗号分隔)流式传输到其上,然后写入尾随 $},它会起作用吗?生成的流应该对 NeoJSON 有好处...?这可能是对问题的 STTCPW 攻击,但 W 很重要 ;-) 而且它应该更快,内存消耗更少,因为 NeoJSON 只会做一次..

只是一个想法,没有尝试过。

于 2016-01-21T11:18:24.253 回答
1

你可以尝试这样的事情:

| 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.

除非这是你已经尝试过的......

于 2016-01-21T12:50:09.313 回答