迈克尔 杰克逊mv_用杰克逊流式传输大型JSON文件– RxJava常见问题解答

迈克尔 杰克逊mv

在上一篇文章中,我们学习了如何解析过大的XML文件并将其转换为RxJava流。 这次让我们看一个大的JSON文件。 我们的示例将基于微小的colors.json,其中包含将近150种这种格式的记录:

{"aliceblue": [240, 248, 255, 1],"antiquewhite": [250, 235, 215, 1],"aqua": [0, 255, 255, 1],"aquamarine": [127, 255, 212, 1],"azure": [240, 255, 255, 1],//...

鲜为人知的事实: 天蓝色也是一种颜色,而Python是蛇。 但是回到RxJava。 这个文件很小,但是我们将用它来学习一些原理。 如果遵循它们,您将能够加载和连续处理任意大,甚至无限长的JSON文件。 首先,标准的“ Jackson ”方式类似于JAXB:将整个文件加载到内存中并将其映射到Java bean。 但是,如果您的文件的大小为兆字节或千兆字节(由于某种原因,您发现JSON是存储千兆字节数据的最佳格式……),则此技术无效。 幸运的是,杰克逊提供了类似于StAX的流模式。

使用Jackson逐令牌加载JSON文件

使用JSON并将其转换为对象集合的标准ObjectMapper没错。 但是为了避免将所有内容加载到内存中,我们必须使用下面的ObjectMapper使用的较低级API。 让我们再次看一下JSON示例:

{"aliceblue": [240, 248, 255, 1],"antiquewhite": [250, 235, 215, 1],//...

从磁盘和内存的角度来看,这是一个单维字节流,我们可以在逻辑上将其汇总为JSON令牌:

START_OBJECT        '{'
FIELD_NAME          'aliceblue'
START_ARRAY         '['
VALUE_NUMBER_INT    '240'
VALUE_NUMBER_INT    '248'
VALUE_NUMBER_INT    '255'
VALUE_NUMBER_INT    '1'
END_ARRAY           ']'
FIELD_NAME          'antiquewhite'
START_ARRAY         '['
VALUE_NUMBER_INT    '250'
VALUE_NUMBER_INT    '235'
VALUE_NUMBER_INT    '215'
VALUE_NUMBER_INT    '1'
END_ARRAY           ']'
...

你明白了。 如果您熟悉编译器理论,这是编译期间的第一步。 编译器将源代码从字符转换为令牌。
但是,如果您了解编译器理论,则可能不是为了生存而解析JSON。 无论如何! Jackson库以这种方式工作,我们可以在没有透明对象映射的情况下使用它:

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;JsonParser parser = new JsonFactory().createParser(new File("colors.json"));
parser.nextToken(); // JsonToken.START_OBJECT;
while (parser.nextToken() != JsonToken.END_OBJECT) {final String name = parser.getCurrentName();parser.nextToken(); // JsonToken.START_ARRAY;parser.nextValue();final int red = parser.getIntValue();parser.nextValue();final int green = parser.getIntValue();parser.nextValue();final int blue = parser.getIntValue();parser.nextValue();parser.getIntValue();System.out.println(name + ": " + red + ", " + green + ", " + blue);parser.nextToken(); // JsonToken.END_ARRAY;
}
parser.close();

…或者如果您摆脱了某些重复,并使代码更易于阅读:

import lombok.Value;JsonParser parser = new JsonFactory().createParser(new File("colors.json"));
parser.nextToken(); // JsonToken.START_OBJECT;
while (parser.nextToken() != JsonToken.END_OBJECT) {System.out.println(readColour(parser));
}
parser.close();//...private Colour readColour(JsonParser parser) throws IOException {final String name = parser.getCurrentName();parser.nextToken(); // JsonToken.START_ARRAY;final Colour colour = new Colour(name,readInt(parser),readInt(parser),readInt(parser),readInt(parser));parser.nextToken(); // JsonToken.END_ARRAY;return colour;
}private int readInt(JsonParser parser) throws IOException {parser.nextValue();return parser.getIntValue();
}@Value
class Colour {private final String name;private final int red;private final int green;private final int blue;private final int alpha;
}

它与RxJava有什么关系? 您可能会猜测–我们可以按需逐块读取此JSON文件。 这使背压机制可以无缝工作:

final Flowable colours = Flowable.generate(() -> parser(new File("colors.json")),this::pullOrComplete,JsonParser::close);

让我解释一下这三个lambda表达式在做什么。 第一个设置了JsonParser我们的可变状态,将用于产生( 拉出 )更多项目:

private JsonParser parser(File file) throws IOException {final JsonParser parser = new JsonFactory().createParser(file);parser.nextToken(); // JsonToken.START_OBJECT;return parser;
}

没有什么花哨。 第二个lambda表达式至关重要。 每当订户希望接收更多项目时,都会调用它。 如果它要求100个项目,则此lambda表达式将被调用100次:

private void pullOrComplete(JsonParser parser, Emitter<Colour> emitter) throws IOException {if (parser.nextToken() != JsonToken.END_OBJECT) {final Colour colour = readColour(parser);emitter.onNext(colour);} else {emitter.onComplete();}
}

当然,如果到达END_OBJECT (关闭整个JSON文件),则表明流已结束。 最后一个lambda表达式仅允许清除状态,例如通过关闭JsonParser和基础File 。 现在想象一下这个JSON文件的大小为数百GB。 有了Flowable<Colour>我们可以安全地以任意速度使用它,而不会冒内存过载的风险。

翻译自: https://www.javacodegeeks.com/2017/09/streaming-large-json-file-jackson-rxjava-faq.html

迈克尔 杰克逊mv

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

@cacheable 是否缓存成功_缓存策略:如何使用缓存来减少磁盘IO?

现代的消息队列&#xff0c;都使用磁盘文件来存储消息。因为磁盘是一个持久化的存储&#xff0c;即使服务器掉电也不会丢失数据。绝大多数用于生产系统的服务器&#xff0c;都会使用多块儿磁盘组成磁盘阵列&#xff0c;这样不仅服务器掉电不会丢失数据&#xff0c;即使其中的一…

Linux 启动/停止/重启 SSH 进程,以及查看 SSH 进程状态的命令

请参考文章《Linux 启动/重启/关闭 MySQL 数据库的命令》

g++ 安装python_以后再也不用“教程”:让人举一反三的python配置环境过程 + 超简单原理概括!...

前言&#xff1a; 前一阵子至少指导了5位学弟学妹小伙伴配置 python 环境。两年前我入门 python 时&#xff0c;也得照着互联网上的资料&#xff0c;一步一步“照猫画虎”&#xff1b;为什么现在自己可以“凭感觉”一气呵成了呢&#xff1f;我想&#xff0c;原因必然是自己对于…

MacBook/MacOS/Mac OS 关于启动/停止/重启服务(进程/程序)的命令

文章目录使用命令 launchctl 停止某个进程使用命令 launchctl 启动某个进程使用命令 launchctl 查看某个进程是否启动使用命令 launchctl 停止某个进程 liaowenongdeair:bin root# sudo launchctl unload -w /System/Library/LaunchDaemons/ssh.plist说明&#xff1a; .plist …

通过Java和Spring Boot应用程序将Gmail用作SMTP服务器

Gmail用户可以使用Gmail的SMTP服务器smtp.gmail.com从其Spring Boot应用程序发送电子邮件。 为此&#xff0c;让我们在应用程序中进行一些设置&#xff1a; 在application.properties文件中提供SMTP连接属性&#xff1a; spring.mail.hostsmtp.gmail.com spring.mail.username…

java面向对象类似atm的题_Java面向对象练习题之银行存取款

编写Java应用程序。首先定义一个描述银行账户的Blank类&#xff0c;包括成员变量“账号”和“存款余额”&#xff0c;成员方法有“存款”、“取款”和“余额查询”。其次&#xff0c;编写一个主类&#xff0c;在主类中测试Blank类的功能。String ZhangHao;double YuE;Blank(Str…

mongodb如何写入图片_CTO之瞳-数据库-MongoDB

MongoDB&#xff0c;常用的NoSql数据库&#xff0c;在https://db-engines.com/en/ranking 里被分类为文档型数据库。​本文从以下五个方面来了解MongoDB (和上一篇一样&#xff0c;基础操作请查询官方文档或者菜鸟教程&#xff09;使用场景存储引擎性能测试索引-B树分片与复制1…

技术停滞_检测和测试停滞的流– RxJava常见问题解答

技术停滞假设您有一个流以不可预测的频率发布事件。 有时您可以预期每秒会有数十条消息&#xff0c;但是偶尔几秒钟都看不到任何事件。 如果您的流是通过Web套接字&#xff0c;SSE或任何其他网络协议传输的&#xff0c;则可能会出现问题。 静默时间过长&#xff08;停顿&#x…

小波滤波器与其他滤波器的区别_滤波器国产 VS 国外

一、滤波器技术及产品类型详细分析几次技术应用的潮流引领了声波射频滤波器技术的发展&#xff0c;而SAW滤波器可以说是军用转民用的技术典范。早期国内的SAW滤波器仅用于国防如雷达、通信等方面需求&#xff1b;而该技术的第一次民用&#xff0c;即用于彩电产业&#xff0c;带…

java stopself_然后,即使我停止了服务,Context.startForegroundService()也没有调用Service.startForeground()...

所以我的应用程序有一些触发服务和通知的远程操作 . 在调用 startForegroundService 和服务尝试启动通知的时间之间&#xff0c;事情可能会发生变化&#xff0c;因此服务会再次检查事物的状态&#xff0c;然后决定要做什么 .因此&#xff0c;如果我的服务决定它不需要运行&…

Unix/Linux/BSD 它们之间的关系以及各自派系的介绍

文章目录一、Unix 是什么二、Unix 派系&#xff08;一&#xff09;BSD 分支1.BSD 是什么2.由 BSD 衍生的闭源 Unix 版本3.由 BSD 衍生的开源 Unix 版本&#xff08;二&#xff09;System V 分支1.System V 是什么2.System V 与 BSD 的版权纠纷&#xff0c;以及 UnixWare 的由来…

arraylist获取前多少位_Java 面试题 :百度前 200 页都在这里

作者&#xff1a;唐尤华&#xff0c;基本概念操作系统中 heap 和 stack 的区别什么是基于注解的切面实现什么是 对象/关系 映射集成模块什么是 Java 的反射机制什么是 ACIDBS与CS的联系与区别Cookie 和 Session的区别fail-fast 与 fail-safe 机制有什么区别get 和 post请求的区…

航空订票系统界面java_Java命令行界面(第21部分):航空公司2

航空订票系统界面java本系列文章的第21篇关于Java中解析命令行参数的文章的重点是Airline 2库。 Airline 2的GitHub项目页面描述了该库&#xff0c;“ Airline是一个Java库&#xff0c;提供了基于注释的框架来解析命令行界面。” 该页面进入状态&#xff1a;航空公司“同时支持…

js map遍历 修改对象里面的值_js中那些方法不改变原来的数组对象

一、map方法 [javascript] view plain copy function fuzzyPlural(single) {var result = single.replace(/o/g, e); //replace也不会修改原来数组的值,这里打印[foot,goose,moose,kangaroo] //alert(single); //下面为新的数组添加了一个元素,但是我们看到在map的时候没有对…

QPW 公告表(tf_notice)

公告表 CREATE TABLE tf_notice (notice_id int(11) NOT NULL AUTO_INCREMENT COMMENT 公告ID,title varchar(300) DEFAULT NULL COMMENT 标题,content varchar(2000) DEFAULT NULL COMMENT 内容,company_id bigint(20) DEFAULT NULL COMMENT 企业ID, # 删掉appraise_id bigin…

python爬虫数据_python爬取数据分析

一.python爬虫使用的模块 1.import requests 2.from bs4 import BeautifulSoup 3.pandas 数据分析高级接口模块 二. 爬取数据在第一个请求中时, 使用BeautifulSoupimport requests # 引用requests库 from bs4 import BeautifulSoup # 引用BeautifulSoup库 res_movies requests…

java 迁移数据_Java 9迁移指南:七个最常见的挑战

java 迁移数据我敢肯定&#xff0c;您已经听说过更新到Java 9并不是一件容易的事&#xff0c;甚至可能是不兼容的更新&#xff0c;而且对于大型代码库而言&#xff0c;迁移毫无意义。 这样做之后&#xff0c;我迁移了一个相当大的旧代码库&#xff0c;我可以告诉你&#xff0c;…

markdown java 代码高亮_MarkdownPad2使用代码高亮插件

MarkdownPad 2有插入代码块的功能&#xff0c;但样式却不尽人意&#xff0c;但又不想换个编辑器&#xff0c;找了挺多相关资料&#xff0c;最后在MarkdownPad 2集成prettify高亮插件。如下相关资料&#xff1a;你可以下载后引用&#xff0c;也可以直接引用bootcdn。具体步骤&am…

QPW 点评阅读日志表(tf_appraise_read_log)

点评阅读日志表 CREATE TABLE tf_appraise_read_log (read_log_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 日志ID,appraise_id bigint(20) DEFAULT NULL COMMENT 点评ID,user_id bigint(20) DEFAULT NULL COMMENT 用户ID,duration int(11) DEFAULT NULL COMMENT 阅读时长…

需求调研 现有系统梳理_对速度的需求,访问现有数据的速度提高了1000倍

需求调研 现有系统梳理了解如何通过使用标准Java 8流和Speedment的In-JVM-Memory加速器将分析数据库应用程序加速1000倍。 Web和移动应用程序有时会很慢&#xff0c;因为后备数据库很慢和/或与数据库的连接施加了延迟。 现代的UI和交互式应用程序需要快速后端&#xff0c;并且…