C# json数据流解析,可解决粘包、断包、坏包问题

来源:互联网 发布:vue.js 实现网页下载 编辑:程序博客网 时间:2024/06/04 01:31

说明

  • 使用 Json.NET
  • 官方例程:https://www.newtonsoft.com/json/help/html/ReadMultipleContentWithJsonReader.htm

  • 使用泛型,可直接对已知数据格式JSON反序列化

  • 如只想分割JSON,可使用 public object Deserialize(JsonReader reader);
  • 欢迎评论补充

代码块

可直接作为类使用

public class JsonParse<T>    {        static MemoryStream fileStream = new MemoryStream();        static StreamWriter outerstr = new StreamWriter(fileStream);        static StreamReader inerstr = new StreamReader(fileStream, true);        //json数据解析方法,返回解析出的数据        static int streamPosition = 0;  //记录解析数据到流的哪个位置        static AutoResetEvent jsonEvent = new AutoResetEvent(true);//调用一次Set()只能继续被阻塞的一个线程,区别ManualResetEvent         public void JsonPush(string cmd)        {            jsonEvent.WaitOne();            fileStream.Position = fileStream.Length;            outerstr.Write(cmd);            outerstr.Flush();            jsonEvent.Set();        }        public IList<T> JsonPop()        {            jsonEvent.WaitOne();            IList<T> roles = new List<T>();            fileStream.Position = streamPosition;            inerstr = new StreamReader(fileStream, true);            JsonTextReader reader = new JsonTextReader(inerstr);            reader.SupportMultipleContent = true;            int readerP = 0;            while (true)            {                try                {                    if (!reader.Read())                    {                        break;                    }                    JsonSerializer serializer = new JsonSerializer();                    serializer.DefaultValueHandling = DefaultValueHandling.Ignore;                    //object ob= serializer.Deserialize(reader);                    T role = serializer.Deserialize<T>(reader);                    roles.Add(role);                    readerP = reader.LinePosition;                }                catch (Exception e)                {                    Console.WriteLine("JsonParse error.");                    try                    {                        byte[] inerstrData = new byte[1];                        Stream s = inerstr.BaseStream;                        s.Seek(streamPosition+readerP, 0);                        s.Read(inerstrData, 0, 1);                        //inerstr.ReadBlock(inerstrData, readerP,1);                        long restLength = fileStream.Length - streamPosition;                        if (inerstrData[0] == 0x7b)                        {                            //s.Close();                            break;                        }                        else                        {                            for (readerP = readerP + 1; readerP <= restLength; readerP++)                            {                                //inerstr.ReadBlock(inerstrData, readerP, 1);                                s.Read(inerstrData, 0, 1);                                if (inerstrData[0] == 0x7b)                                {                                    //s.Close();                                    break;                                }                            }                            if (readerP > restLength-5)                            {                                //s.Close();                                break;                            }                            else                            {                                streamPosition += readerP;                                readerP = 0;                                fileStream.Position = streamPosition;                                inerstr = new StreamReader(fileStream, true);                                reader = new JsonTextReader(inerstr);                                reader.SupportMultipleContent = true;                                //s.Close();                                continue;                            }                        }                    }                    catch (Exception ex)                    {                        fileStream = new MemoryStream();                        outerstr = new StreamWriter(fileStream);                        inerstr = new StreamReader(fileStream, true);                        break;                    }                }                //DataTable dt = new DataTable();                //dt = JsonConvert.DeserializeObject<DataTable>(reader.);                           }            streamPosition += readerP;            if ((streamPosition > 10240) && (streamPosition == fileStream.Length))            {                fileStream = new MemoryStream();                outerstr = new StreamWriter(fileStream);                inerstr = new StreamReader(fileStream, true);                streamPosition = 0;            }            jsonEvent.Set();            return roles;        }    }