java json返回文件流_如何将JSON文件转换为Java 8对象流?

我无法找到一个好的解决方案,我需要一个特定的案例:

我有一个> 1GB的JSON文件(顶级JSON数组,有成千上万的大对象),使用普通的Jackson映射器在访问生成的Java对象数组时导致崩溃.

我发现使用Jackson Streaming API的示例丢失了极具吸引力的对象映射,当然也不允许通过(显然适当的)Java 8 Streaming API访问对象.

这是一个使用的快速示例:

//Use the JSON File included as a resource

ClassLoader classLoader = SleepReader.class.getClassLoader();

File dataFile = new File(classLoader.getResource("example.json").getFile());

//Simple example of getting the Sleep Objects from that JSON

new JsonArrayStreamDataSupplier<>(dataFile, Sleep.class) //Got the Stream

.forEachRemaining(nightsRest -> {

System.out.println(nightsRest.toString());

});

这是example.json中的一些JSON

[

{

"date": "August 17, 2015",

"hours": 7,

"minutes": 10

},

{

"date": "August 19, 2015",

"hours": 4,

"minutes": 46

},

{

"date": "August 19, 2015",

"hours": 7,

"minutes": 22

},

{

"date": "August 21, 2015",

"hours": 4,

"minutes": 48

},

{

"date": "August 21, 2015",

"hours": 6,

"minutes": 1

}

]

如果你不想去GitHub(你应该),这里是包装类本身:

/**

* @license APACHE LICENSE, VERSION 2.0 http://www.apache.org/licenses/LICENSE-2.0

* @author Michael Witbrock

*/

package com.michaelwitbrock.jacksonstream;

import com.fasterxml.jackson.core.JsonFactory;

import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.databind.JsonNode;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;

import java.io.IOException;

import java.util.Iterator;

import java.util.Spliterators;

import java.util.stream.Stream;

import java.util.stream.StreamSupport;

public class JsonArrayStreamDataSupplier implements Iterator {

/*

* This class wraps the Jackson streaming API for arrays (a common kind of

* large JSON file) in a Java 8 Stream. The initial motivation was that

* use of a default objectmapper to a Java array was crashing for me on

* a very large JSON file (> 1GB). And there didn't seem to be good example

* code for handling Jackson streams as Java 8 streams, which seems natural.

*/

static ObjectMapper mapper = new ObjectMapper();

JsonParser parser;

boolean maybeHasNext = false;

int count = 0;

JsonFactory factory = new JsonFactory();

private Class type;

public JsonArrayStreamDataSupplier(File dataFile, Class type) {

this.type = type;

try {

// Setup and get into a state to start iterating

parser = factory.createParser(dataFile);

parser.setCodec(mapper);

JsonToken token = parser.nextToken();

if (token == null) {

throw new RuntimeException("Can't get any JSON Token from "

+ dataFile.getAbsolutePath());

}

// the first token is supposed to be the start of array '['

if (!JsonToken.START_ARRAY.equals(token)) {

// return or throw exception

maybeHasNext = false;

throw new RuntimeException("Can't get any JSON Token fro array start from "

+ dataFile.getAbsolutePath());

}

} catch (Exception e) {

maybeHasNext = false;

}

maybeHasNext = true;

}

/*

This method returns the stream, and is the only method other

than the constructor that should be used.

*/

public Stream getStream() {

return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, 0), false);

}

/* The remaining methods are what enables this to be passed to the spliterator generator,

since they make it Iterable.

*/

@Override

public boolean hasNext() {

if (!maybeHasNext) {

return false; // didn't get started

}

try {

return (parser.nextToken() == JsonToken.START_OBJECT);

} catch (Exception e) {

System.out.println("Ex" + e);

return false;

}

}

@Override

public T next() {

try {

JsonNode n = parser.readValueAsTree();

//Because we can't send T as a parameter to the mapper

T node = mapper.convertValue(n, type);

return node;

} catch (IOException | IllegalArgumentException e) {

System.out.println("Ex" + e);

return null;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值