Сохранение записей в JSON, добавление их и анализ - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь построить с GSON что-то вроде базы данных.Я хочу хранить записи одного и того же объекта и иметь возможность добавлять новые записи в любое время.Также я пытаюсь создать парсер, который будет переносить все объекты из json в ArrayList.Как я могу это сделать?В настоящее время я написал что-то вроде этого:

public void addRecord(Record record) throws IOException {

    JsonWriter writer = new JsonWriter(new FileWriter("/file.json", true));

    writer.setIndent(" ");
    gson.toJson(record, Record.class, writer);
    writer.close();
}

Но intelliJ говорит мне, что стандарт JSON допускает только одно значение верхнего уровня.Как этого избежать?Как я понимаю, файл должен содержать только один список, и я должен добавлять новые объекты к нему, но я не знаю как.Кроме того, как разобрать их в ArrayList?

1 Ответ

0 голосов
/ 19 мая 2018

Но intelliJ говорит мне, что стандарт JSON допускает только одно значение верхнего уровня.

Да.То, что вы реализовали, является сцепленным JSON (см. more ).Вы все еще можете использовать его, но ваши файлы записей не будут анализироваться с помощью JSON-совместимых инструментов.Если вы не хотите использовать «сырые» потоки JSON, вы можете реализовать потоки на основе массива JSON.Это требует некоторой работы, но позволит вам создавать и использовать действительные документы JSON.

final class JsonStreams {

    private JsonStreams() {
    }

    @SuppressWarnings("resource")
    static void copy(final JsonReader reader, final JsonWriter writer)
            throws IOException {
        int level = 0;
        loop:
        for ( JsonToken token = reader.peek(); token != null; token = reader.peek() ) {
            switch ( token ) {
            case BEGIN_ARRAY:
                reader.beginArray();
                writer.beginArray();
                ++level;
                break;
            case END_ARRAY:
                reader.endArray();
                writer.endArray();
                if ( --level == 0 ) {
                    return;
                }
                break;
            case BEGIN_OBJECT:
                reader.beginObject();
                writer.beginObject();
                ++level;
                break;
            case END_OBJECT:
                reader.endObject();
                writer.endObject();
                if ( --level == 0 ) {
                    return;
                }
                break;
            case NAME:
                final String name = reader.nextName();
                writer.name(name);
                break;
            case STRING:
                final String s = reader.nextString();
                writer.value(s);
                break;
            case NUMBER:
                final Number n = new BigDecimal(reader.nextString());
                writer.value(n);
                break;
            case BOOLEAN:
                final boolean b = reader.nextBoolean();
                writer.value(b);
                break;
            case NULL:
                reader.nextNull();
                writer.nullValue();
                break;
            case END_DOCUMENT:
                break loop;
            default:
                throw new AssertionError(token);
            }
        }
    }

    static void appendToArray(final JsonReader jsonReader, final JsonWriter jsonWriter, final Consumer<? super JsonWriter> consumer)
            throws IOException {
        // Making JsonReader set to END_DOCUMENT if there is a blank/whitespace document
        try {
            jsonReader.hasNext();
        } catch ( final EOFException ignored ) {
        }
        // Checking the outer-most JSON token
        final JsonToken beginJsonToken = jsonReader.peek();
        switch ( beginJsonToken ) {
        // If it's a blank/whitespace document, then just write a single row
        case END_DOCUMENT:
            jsonWriter.beginArray();
            consumer.accept(jsonWriter);
            jsonWriter.endArray();
            break;
        // If the document starts with [, then unroll all its values
        case BEGIN_ARRAY:
            jsonReader.beginArray();
            jsonWriter.beginArray();
            final JsonToken endJsonToken = jsonReader.peek();
            if ( endJsonToken != JsonToken.END_ARRAY ) {
                // Copy all existing values
                while ( jsonReader.hasNext() ) {
                    final JsonToken rowJsonToken = jsonReader.peek();
                    switch ( rowJsonToken ) {
                    case BEGIN_ARRAY:
                    case BEGIN_OBJECT:
                    case STRING:
                    case NUMBER:
                    case BOOLEAN:
                    case NULL:
                        copy(jsonReader, jsonWriter);
                        break;
                    // The rest of tokens must never happen because we copy values
                    case END_ARRAY:
                    case END_OBJECT:
                    case NAME:
                    case END_DOCUMENT:
                    default:
                        throw new AssertionError(rowJsonToken);
                    }
                }
            }
            consumer.accept(jsonWriter);
            // End the document with ]
            jsonReader.endArray();
            jsonWriter.endArray();
            break;
        default:
            throw new JsonParseException("Unexpected outer token: " + beginJsonToken);
        }
    }

}
public static void main(final String... args)
        throws IOException {
    final Iterable<String> resourceNames = ImmutableList.of("1-blank.json", "2-empty.json", "3-some.json");
    for ( final String resourceName : resourceNames ) {
        try ( final JsonReader jsonReader = Resources.getPackageResourceJsonReader(Q50418170.class, resourceName) ) {
            final Writer writer = new StringWriter();
            final JsonWriter jsonWriter = new JsonWriter(writer);
            JsonStreams.appendToArray(jsonReader, jsonWriter, jw -> {
                gson.toJson(fooBar(1, 2), jw);
                gson.toJson(fooBar(3, 4), jw);
                gson.toJson(fooBar(5, 6), jw);
            });
            System.out.println(writer);
        }
    }
}

private static JsonElement fooBar(final int foo, final int bar) {
    final JsonObject jsonObject = new JsonObject();
    jsonObject.add("foo", new JsonPrimitive(foo));
    jsonObject.add("bar", new JsonPrimitive(bar));
    return jsonObject;
}

Тестовые документы, приведенные выше:

1-blank.json

2-empty.json

[
]

3-some.json

Этот документ отформатирован намеренно, но я буду хранить документы JSON минимизированными (поэтому, Я бы не использовал setIndent).

[
    {
        "foo": 0,
        "bar": 0,
        "baz": [
            1,
            2,
            3
        ]
    }
]

Тест для вышеуказанных документов даст следующий вывод

[{"foo":1,"bar":2},{"foo":3,"bar":4},{"foo":5,"bar":6}]
[{"foo":1,"bar":2},{"foo":3,"bar":4},{"foo":5,"bar":6}]
[{"foo":0,"bar":0,"baz":[1,2,3]},{"foo":1,"bar":2},{"foo":3,"bar":4},{"foo":5,"bar":6}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...