5

次のような多くの要素を含むjsonファイルがあります。

{ 
"code" : "hfuiew89", 
"type" : "location", 
"coordinates" : [ { "lat" : 40.9861, "lon" : 29.1046, "index" : 1 }, 
          { "lat" : 40.9976, "lon" : 29.1153, "index" : 2 }, 
          { "lat" : 40.9809, "lon" : 29.2194, "index" : 3 }] 
}
{ 
"code" : "klsdsjh", 
"type" : "location", 
"relatedTags" : [ "kolmha" ], 
"coordinates" : [ { "lat" : 40.9808, "lon" : 29.1605, "index" : 1 }, 
              { "lat" : 40.9965, "lon" : 29.1672, "index" : 2 }] 
}

そのファイルを gson で読みたいのですが、見つかったすべての例は 1 つの要素のみです。したがって、最初のものを読み取った後、「Expected EOF」例外がスローされます。どうすればこれを克服できますか?

4

2 に答える 2

10

その価値のために...

次のステートメントは正しくありません。Gson には、そのような JSON シーケンスの逆シリアル化を単純に処理する機能が組み込まれていません。(コメントを参照してください。)

JSON から Java API への切り替えがオプションである場合、Jacksonには、以下に示すようにそのような機能があります。

入力.json

{
"name":"A"
}
{
"name":"B"
}

JacksonFoo.java

import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static com.fasterxml.jackson.annotation.PropertyAccessor.FIELD;

import java.io.File;
import java.util.Iterator;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper().setVisibility(FIELD, ANY);
    Iterator<Thing> thingsIterator = mapper.reader(Thing.class).readValues(new File("input.json"));
    while (thingsIterator.hasNext())
    {
      System.out.println(thingsIterator.next());
    }
  }
}

class Thing
{
  private String name;

  @Override
  public String toString()
  {
    return String.format("Thing: name=%s", name);
  }
}

出力:

Thing: name=A
Thing: name=B

更新: Gson を使用した同様のソリューション。

GsonFoo.java

import java.io.FileReader;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonStreamParser;

public class GsonFoo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new GsonBuilder().create();

    JsonStreamParser parser = new JsonStreamParser(new FileReader("input.json"));
    while(parser.hasNext())
    {
      System.out.println(gson.fromJson(parser.next(), Thing.class));
    }
  }
}
于 2012-06-29T03:24:36.833 に答える
3

グレッグは正しいです。これは正しくないJSONです。有効なJSONを生成する必要があります。つまり、最初に「[」を追加し、最後に「]」を追加し、各要素をコンマ( "、")で区切ります。それがJSONオブジェクトのJSON配列であること。

ただし、使用している形式を変更できない場合は、「整形式のJSONフラグメントの連結を含む文字列」と見なしてください。そのようにアプローチして、大きな文字列を小さくて有効なjson文字列に分割し、それらを1つずつ解析します。

大きな文字列を単一のフラグメントに分割するには、角かっこを数えるだけです。ものをバッファにコピーする「プリパーサー」(StringBuilder?)を使用すると、「{」に遭遇するたびにカウンターをインクリメントし、「}」を出力するたびにカウンターをインクリメントし、カウンターがゼロパスの場合解析のためにgsonへのバッファ文字列。バッファをクリアしてファイルの最後に進みます。

そのプリパーサーを使用して有効なjsonに変換することもできます。カウンターがゼロに達したときに「、」を追加し、1回の解析ですべてをgsonに渡すだけですが、それはすべてをramにロードすることを意味する可能性があります。ファイルの大きさがわかりません。

于 2012-06-28T22:36:02.190 に答える