日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

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

發布時間:2023/12/3 javascript 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用杰克逊流式传输大型JSON文件– RxJava常见问题解答 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一篇文章中,我們學習了如何解析過大的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

總結

以上是生活随笔為你收集整理的用杰克逊流式传输大型JSON文件– RxJava常见问题解答的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。