简体   繁体   English

如何从json流反序列化多个对象?

[英]How to deserialize multiple objects from a json stream?

Ok, I have asked questions about something like this before, but this is a different subject, so i feel i should make a new topic about it. 好的,我之前曾经问过类似的问题,但这是一个不同的主题,所以我觉得我应该对此做一个新的话题。 I'm sorry if this is something i should not have done... 如果这是我不应该做的事,我感到抱歉。

Anyway: 无论如何:

I'm currently reading a twitterfeed and trying to convert it to lose (status) objects. 我目前正在阅读twitterfeed,并尝试将其转换为丢失(状态)对象。 The code i have now is as follows but fails: 我现在拥有的代码如下,但失败了:

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
    {

    }

}

The idea is: Copy the stream into another stream. 这个想法是:将流复制到另一个流。 and keep trying to read it untill an status object is discovered. 并继续尝试读取它,直到发现状态对象为止。 This was ment to prevent the stream for being to little, so it had chance to grow. 这是为了防止流量太少,所以它有机会增长。 Ofcourse the stream does not always start at the start of an object, or can be corrupt. 当然,流并不总是从对象的开头开始,否则可能会损坏。

Now i did find the method IsStartObject , and i think i should use it. 现在我确实找到了IsStartObject方法,我认为我应该使用它。 Though i have no experience with streams and i can never find a good example of how to use this. 虽然我没有流的使用经验,但是我永远找不到如何使用它的好例子。

Is there anyone who can explain to me how to read multiple objects from the stream so i can write them into a list or w/e. 有谁可以向我解释如何从流中读取多个对象,以便我可以将它们写入列表或w / e。 I really can't find any good examples on the internets.. 我真的在互联网上找不到任何好的例子。

Thank you very much for trying!!! 非常感谢您的尝试!

I used Json.Net library and this extension class that makes use of DynamicObject to parse streaming json objects 我使用了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);
}

This is an implementation of LB 's suggestion for splitting by counting the nesting level of { and }. 这是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;
  }
}

Here's a test 这是一个测试

[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);
    }
  }

The implementation of GenerateStreamFromString is here GenerateStreamFromString的实现在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM