Чтение нескольких элементов из файла JSON

у меня есть файл 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, но все примеры, которые я нашел, только для одного элемента. поэтому после прочтения первого из них выбрасывает «ожидаемый EOF»; исключение. как я могу преодолеть это?

 Greg Kopff28 июн. 2012 г., 23:59
JSON этоmeant быть единым целым (будь то объект или массив), а у вас есть несколько объектов. В этой ситуации вам действительно нужен массив на верхнем уровне, в котором каждый объект является элементом. Можете ли вы повлиять наgeneration этого JSON, или вы застряли в этом формате?

Ответы на вопрос(2)

Решение Вопроса

Грег прав, это неверный JSON, и вы должны попытаться сгенерировать действительный JSON, то есть prepend & quot; [& quot; в начале добавьте & quot;] & quot; в конце и разделите каждый элемент запятой (& quot;, & quot;), чтобы это был массив JSON объекта JSON.

Однако, если вы не можете изменить имеющийся у вас формат, считайте это «строкой, содержащей объединение хорошо сформированных фрагментов JSON». Подходя таким образом, разбейте большую строку на более мелкие, допустимые строки json и проанализируйте их одну за другой.

Чтобы разбить большую строку на отдельные фрагменты, вы можете просто посчитать скобки. С «предварительным анализатором»; который копирует содержимое в буфер (StringBuilder?), увеличивает счетчик каждый раз, когда встречает «{», уменьшает его каждый раз, когда он вводит «}», и, если счетчик равен нулю, передает строку буфера gson для разбора, очистите буфер и перейдите к концу файла.

Вы даже можете использовать этот предварительный анализатор, чтобы преобразовать его в действительный json, просто добавив & quot;, & quot; когда счетчик достигнет нуля и передаст все в gson для одного анализа, но это может означать загрузку всего в ram, и я не знаю, насколько велик ваш файл.

 29 июн. 2012 г., 01:04
Да, нет закрывающих тегов ... очень хорошо, если вам не нужно редактировать файл json вручную или иметь очень очень простую структуру, но что, если последние несколько строк - это десятки закрывающих скобок? : D Если бы все, что нам было нужно, это лучший формат, чем XML, для межмашинных коммуникаций, JSON даже слишком многословен для этой задачи ... но я думаю, что мы уходим в оффтоп: D
 29 июн. 2012 г., 01:14
Согласовано. В любом случае, это все об Avro или Thrift: P
 29 июн. 2012 г., 00:53
Да, это то, что я пытался выразить: большой массив json с одним файлом и один вызов для анализа могут показаться более простыми, но это также может означать загрузку всего в ram; пока идет "шаг за шагом" не могли бы вы позволить обрабатывать сущности один за другим ... это снова SAX против DOM, но теперь, когда он называется JSON, он делает звучание намного более громким.
 29 июн. 2012 г., 00:47
Следуя этому, вы можете просто создать свой файл в виде массива объектов JSON. Однако вы можете столкнуться с проблемами памяти, если в массиве слишком много объектов. В противном случае лучше использовать разделенную строку сущностей JSON, которая позволит вам загружать только часть файла за раз.
 29 июн. 2012 г., 00:56
Хаха, так правда. Хотя JSON кажется менее многословным (например, без закрывающих тегов), он также предоставляет очень простой способ передачи данных в Javascript, что сегодня очень модно и, следовательно, вероятно, является одной из причин большого роста JSON.

За что это стоит ...

Следующее утверждение неверно. Gson не имеет встроенной функции для простой десериализации такой последовательности JSON. (Смотрите комментарии.)

Если переключение JSON-в / из-Java APIs является вариантом,Джексон имеет такую особенность, как показано ниже.

input.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);
  }
}

Output:

Thing: name=A
Thing: name=B

Update: Аналогичное решение с использованием 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));
    }
  }
}
 30 июн. 2012 г., 00:01
Обновил ответ соответственно.
 29 июн. 2012 г., 20:45
Ах, аккуратно. Я был брошен использованием слова «поток» в GSON API. Я просто предположил, что "Поток" ссылается на синтаксический анализ JSON по одному потоковому токену за раз, в отличие от привязки данных JSON к объектам / массивам.
 08 июн. 2015 г., 11:47
Это именно то, что я искал. Это чрезвычайно полезно, когда вы хотите эффективно записать несколько узлов JSON в файл: вы просто добавляете новый элемент вместо разбора массива, добавляете элемент и записываете все это обратно на диск.
 29 июн. 2012 г., 07:42
Этот пост неверен. У Gson есть такая (неправильная) особенность. Он называется JsonStreamParser, а документация здесь:google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/…

Ваш ответ на вопрос