如何从一个文件中读取大量JSON-

时间:2019-03-24 18:34:48

标签: java android json file gson

我不知道如何在Android中读取大量JSON-s的文件。我什至不知道JSON中有多少个元素。这是JSON的一部分:

{
  "distance" : 0.0,
  "lat" : 52.297819,
  "lon" : 20.937653,
  "realTime" : 1553448972482,
  "speed" : "NaN",
  "time" : 0.0
}{
  "pulse" : 77,
  "rr" : [ 788 ],
  "time" : 1553448976957
}{
  "distance" : 0.0,
  "lat" : 52.297819,
  "lon" : 20.937653,
  "realTime" : 1553448977481,
  "speed" : "NaN",
  "time" : 0.0
}

我创建了两个模型DTO类:

 public class GpsDTO{
    double lat;
    double lon;
    double speed;
    double distance;
    double time;
    long realTime;
}
 public class HeartDTO{
    long time;
    int pulse;
    int[] rr;
}

,我尝试使用库GSON,但是它不起作用。

Gson gson = new GsonBuilder().setLenient().create();
try {
    GpsDTO gpsDTO = gson.fromJson(new FileReader(path),GpsDTO.class);
} catch (Exception  e) {
    e.printStackTrace();
}

1 个答案:

答案 0 :(得分:1)

提出的JSON有效负载无效。默认情况下,Gson不会读取无效的JSON有效负载。我们需要为其实现自定义反序列化器。在这种情况下,JSON结构是JSON object-es的列表。我们可以使用JsonReader并流API。最快的方法是阅读一次,但是更容易阅读两次:

  • 第一次阅读以查找类和适配器的顺序
  • 第二遍阅读,使用给定的i - JSON objects反序列化i - adapter

要匹配实现下面的适配器,请使用JSON对象(findAdapters方法)中的所有属性。如果这不是您所需要的最佳算法,请实施其他符合要求的算法:

class MultiJsonReader {

    // constant list of properties for each class
    private final List<String> HEART_PROPS = Arrays.asList("pulse", "rr", "time");
    private final List<String> GPS_PROPS = Arrays.asList("lat", "lon", "distance", "speed", "realTime", "time");

    private final Gson gson;

    public MultiJsonReader(Gson gson) {
        this.gson = gson;
    }

    public List<Object> readAll(File jsonFile) throws IOException {
        List<TypeAdapter<?>> adapters;
        // read first time for finding types and adapters
        try (JsonReader jsonReader = gson.newJsonReader(new FileReader(jsonFile))) {
            jsonReader.setLenient(true);
            adapters = findAdapters(gson, jsonReader);
        }

        List<Object> objects = new ArrayList<>();

        // read second time for deserialising
        try (JsonReader jsonReader = gson.newJsonReader(new FileReader(jsonFile))) {
            jsonReader.setLenient(true);
            for (TypeAdapter<?> adapter : adapters) {
                objects.add(adapter.read(jsonReader));
            }
        }

        return objects;
    }

    private List<TypeAdapter<?>> findAdapters(Gson gson, JsonReader jsonReader) throws IOException {
        List<TypeAdapter<?>> adapters = new ArrayList<>();

        while (jsonReader.peek() != JsonToken.END_DOCUMENT) {
            List<String> names = new ArrayList<>();

            jsonReader.beginObject();
            while (jsonReader.peek() != JsonToken.END_OBJECT) {
                names.add(jsonReader.nextName());
                jsonReader.skipValue();
            }
            jsonReader.endObject();

            Class<?> clazz = getClassForProperties(names);
            adapters.add(gson.getAdapter(clazz));
        }

        return adapters;
    }

    private Class<?> getClassForProperties(List<String> properties) {
        if (HEART_PROPS.containsAll(properties)) {
            return HeartDTO.class;
        }
        if (GPS_PROPS.containsAll(properties)) {
            return GpsDTO.class;
        }

        throw new IllegalArgumentException("Properties are not known " + properties);
    }
}

用法示例:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder().create();
        MultiJsonReader reader = new MultiJsonReader(gson);
        List<Object> objects = reader.readAll(jsonFile);

        objects.forEach(System.out::println);
    }
}

对于您的JSON有效负载打印:

GpsDTO{lat=52.297819, lon=20.937653, speed=NaN, distance=0.0, time=0.0, realTime=1553448972482}
HeartDTO{time=1553448976957, pulse=77, rr=[788]}
GpsDTO{lat=52.297819, lon=20.937653, speed=NaN, distance=0.0, time=0.0, realTime=1553448977481}