gpt4 book ai didi

java - 将记录保存在 json 中附加它们并解析

转载 作者:行者123 更新时间:2023-11-30 10:15:33 26 4
gpt4 key购买 nike

我正在尝试使用 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?

最佳答案

But intelliJ tells me that JSON standard allows only one top-level value.

是的。您实现的是串联的 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-空白.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}]

关于java - 将记录保存在 json 中附加它们并解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50418170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com