Как десериализовать несколько объектов из потока JSON? - PullRequest
1 голос
/ 17 января 2012

Хорошо, я задавал вопросы о чем-то подобном раньше, но это другая тема, поэтому я чувствую, что должен создать новую тему об этом. Извините, если это то, чего я не должен был делать ...

В любом случае:

Я сейчас читаю твиттер и пытаюсь преобразовать его в потерянные (статусные) объекты. Код, который я сейчас имею, выглядит следующим образом, но не работает:

webRequest = (HttpWebRequest)WebRequest.Create(stream_url);
webRequest.Credentials = new NetworkCredential(username, password);
webRequest.Timeout = -1;
webResponse = (HttpWebResponse)webRequest.GetResponse();
Encoding encode = Encoding.GetEncoding("utf-8");
responseStream = new StreamReader(webResponse.GetResponseStream(), encode);
int i = 0;

//Read the stream.
while (_running)
{
    jsonText = responseStream.ReadLine();

    byte[] sd = Encoding.Default.GetBytes(jsonText);
    stream.Write(sd, i, i + sd.Length);

    try
    {
        status s = json.ReadObject(stream) as status;
        if (s != null)
        {
            //write s to a file/collection or w/e
            i = 0;
        }
    }
    catch
    {

    }

}

Идея такова: скопировать поток в другой поток. и продолжайте пытаться прочитать его, пока не будет обнаружен объект статуса. Это было сделано, чтобы не допустить, чтобы поток был маленьким, поэтому у него была возможность расти. Конечно, поток не всегда начинается с начала объекта или может быть поврежден.

Теперь я нашел метод IsStartObject и думаю, что должен его использовать. Хотя у меня нет опыта работы с потоками, и я никогда не смогу найти хороший пример того, как это использовать.

Есть ли кто-нибудь, кто может объяснить мне, как читать несколько объектов из потока, чтобы я мог записать их в список или w / e. Я действительно не могу найти хороших примеров в интернете ..

Большое спасибо за попытку !!!

Ответы [ 2 ]

1 голос
/ 17 января 2012

Я использовал библиотеку Json.Net и этот класс расширения , который использует DynamicObject для анализа потоковых объектов json

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://stream.twitter.com/1/statuses/sample.json");
webRequest.Credentials = new NetworkCredential("...", "......");
webRequest.Timeout = -1;
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader responseStream = new StreamReader(webResponse.GetResponseStream());

string line;
while (true)
{
    line = responseStream.ReadLine();
    dynamic obj = JsonUtils.JsonObject.GetDynamicJsonObject(line);
    if(obj.user!=null)
        Console.WriteLine(obj.user.screen_name + " => " + obj.text);
}
0 голосов
/ 29 мая 2013

Это реализация предложения LB для разбиения путем подсчета уровня вложенности {и}.

public static IEnumerable<string> JsonSplit(this StreamReader input, char openChar = '{', char closeChar = '}',
  char quote='"', char escape='\\')
{
  var accumulator = new StringBuilder();
  int count = 0;
  bool gotRecord = false;
  bool inString = false;
  while (!input.EndOfStream)
  {
    char c = (char)input.Read();
    if (c == escape)
    {
      accumulator.Append(c);
      c = (char)input.Read();
    }
    else if (c == quote)
    {
      inString = !inString;
    }
    else if (inString)
    {
    }
    else if (c == openChar)
    {
      gotRecord = true;
      count++;
    }
    else if (c == closeChar)
    {
      count--;
    }
    accumulator.Append(c);
    if (count != 0 || !gotRecord) continue;
    // now we are not within a block so 
    string result = accumulator.ToString();
    accumulator.Clear();
    gotRecord = false;
    yield return result;
  }
}

Вот тест

[TestClass]
  public class UnitTest1
  {
    [TestMethod]
    public void TestMethod1()
    {
      string text = "{\"a\":1}{\"b\":\"hello\"}{\"c\":\"oh}no!\"}{\"d\":\"and\\\"also!\"}";
      var reader = FromStackOverflow.GenerateStreamFromString(text);
      var e = MyJsonExtensions.JsonSplit(reader).GetEnumerator();
      e.MoveNext();
      Assert.AreEqual("{\"a\":1}", e.Current);
      e.MoveNext();
      Assert.AreEqual("{\"b\":\"hello\"}", e.Current);
      e.MoveNext();
      Assert.AreEqual("{\"c\":\"oh}no!\"}", e.Current);
      e.MoveNext();
      Assert.AreEqual("{\"d\":\"and\\\"also!\"}", e.Current);
    }
  }

Реализация GenerateStreamFromString здесь

...