【发布时间】:2020-09-12 14:55:37
【问题描述】:
我有一个相当大的 json 文件,我使用我的 Flutter 应用程序从一个大约 200MB 的 web api 下载了该文件
final response = Dio().get(uri, options: Options(responseType: ResponseType.plain));
(使用默认的 Dio 选项也使用 json 解码,导致内存不足异常。 这不是我的问题的直接部分,但也许有帮助)
现在问题在获取json字符串后开始。 当我在响应正文上使用 jsonDecode 时,我的内存不足。 (也许 Dio 使用的功能相同?)
final data = jsonDecode(response.body); 内存不足
json 对象本身是一个数组,里面有很多项,格式如下:
[
{"data": {independent data1}},
{"data": {independent data2}},
...
]
我会很好地一次解码一项而不是一次解码所有内容以减少内存使用。有没有另一种方法来处理这个数组中的所有项目?类似的东西
jsonArrayDecode(response.body, onItemDecode: (item) { /*do stuff with item */ });
还是我必须自己写一个可以顺序解码的json阅读器?
【问题讨论】:
-
尝试将
JsonDecoder用作StreamTransformer -
我不确定您将 JsonDecoder 用作 StreamTransformer 到底是什么意思,但经过一些试验后,我将 Dio Transformer 替换为自定义的,并将 transformResponse 函数覆盖为
Future transformResponse(RequestOptions options, ResponseBody response) { return JsonDecoder().bind(utf8.decoder.bind(response.stream)).first; },它的工作原理不够坠毁。在 GC 中断的情况下处理 json 的速度仍然很慢,但也许这已经很好了。感谢您的意见! -
我的意思不是
Dio Transformer- 我的意思是Stream.transform() 以StreamTransformer 为参数的方法,更多信息在这里:dart.dev/articles/archive/converters-and-codecs -
类似:
Stream.value('[{"header": {"header1": -1}}, ' + '{"k1": 111, "k2": 222}, {"k3": 333}, ' * 2 + ' {"footer": 999}]') .transform(JsonDecoder(reviver)) .listen((data) { print('=' * 64); print(data); });- 这里reviver用于在解析单个项目时选择它们 - 这意味着理论上您可以拥有无限的输入数据流并在项目到来时对其进行处理 -
嗯,好吧,但是如果使用它,那么来自
listen的onData函数只会在整个列表已经转换时调用一次,或者我可以使用恢复器以产生更多输出?或者我可以忽略监听并只处理 reviver 中的数据吗?类似response.data.stream.cast<List<int>>().transform(utf8.decoder).transform(JsonDecoder((key, value) { if (/*object is top level item*/) processItem(); return null; else return value }))?