Как читать много JSON-ов из одного файла - PullRequest
1 голос
/ 24 марта 2019

Я понятия не имею, как читать файлы с большим количеством JSON -s в Android.Я даже не знаю, сколько элементов в 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 Ответ

1 голос
/ 25 марта 2019

Представлено 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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...