我找不到一个好的解决方案,但我需要一个特定的案例:我有一个超过1GB的JSON文件(顶级JSON数组,包含数万个大型对象),使用常规的Jackson映射器会在访问生成的Java对象数组时导致崩溃。
我找到的使用Jackson流API的示例失去了如此吸引人的对象映射,并且肯定不允许通过(明显适当的)Java 8流API访问对象。
现在代码已上传至GitHub
这是一个快速使用的示例:
ClassLoader classLoader = SleepReader.class.getClassLoader();
File dataFile = new File(classLoader.getResource("example.json").getFile());
new JsonArrayStreamDataSupplier<>(dataFile, Sleep.class)
.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(建议您前往),这里是包装类本身:
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<T> implements Iterator<T> {
static ObjectMapper mapper = new ObjectMapper();
JsonParser parser;
boolean maybeHasNext = false;
int count = 0;
JsonFactory factory = new JsonFactory();
private Class<T> type;
public JsonArrayStreamDataSupplier(File dataFile, Class<T> type) {
this.type = type;
try {
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());
}
if (!JsonToken.START_ARRAY.equals(token)) {
maybeHasNext = false;
throw new RuntimeException("Can't get any JSON Token fro array start from "
+ dataFile.getAbsolutePath());
}
} catch (Exception e) {
maybeHasNext = false;
}
maybeHasNext = true;
}
public Stream<T> getStream() {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, 0), false);
}
@Override
public boolean hasNext() {
if (!maybeHasNext) {
return false;
}
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();
T node = mapper.convertValue(n, type);
return node;
} catch (IOException | IllegalArgumentException e) {
System.out.println("Ex" + e);
return null;
}
}
}