首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Json.NET可以序列化/反序列化到流/从流中序列化吗?

Json.NET可以序列化/反序列化到流/从流中序列化吗?
EN

Stack Overflow用户
提问于 2011-11-17 03:41:34
回答 4查看 205.3K关注 0票数 174

我听说Json.NET比DataContractJsonSerializer快,想试一试……

但是我在JsonConvert上找不到任何接受流而不是字符串的方法。

例如,为了在WinPhone上反序列化一个包含JSON的文件,我使用以下代码将文件内容读入一个字符串,然后反序列化为JSON。在我的(非常特别的)测试中,它似乎比使用DataContractJsonSerializer直接从流中反序列化要慢4倍……

代码语言:javascript
复制
// DCJS
DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(Constants));
Constants constants = (Constants)dc.ReadObject(stream);

// JSON.NET
string json = new StreamReader(stream).ReadToEnd();
Constants constants = JsonConvert.DeserializeObject<Constants>(json);

我做错了吗?

EN

回答 4

Stack Overflow用户

发布于 2014-03-27 22:02:57

代码语言:javascript
复制
public static void Serialize(object value, Stream s)
{
    using (StreamWriter writer = new StreamWriter(s))
    using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
    {
        JsonSerializer ser = new JsonSerializer();
        ser.Serialize(jsonWriter, value);
        jsonWriter.Flush();
    }
}

public static T Deserialize<T>(Stream s)
{
    using (StreamReader reader = new StreamReader(s))
    using (JsonTextReader jsonReader = new JsonTextReader(reader))
    {
        JsonSerializer ser = new JsonSerializer();
        return ser.Deserialize<T>(jsonReader);
    }
}
票数 101
EN

Stack Overflow用户

发布于 2013-07-29 21:42:10

我已经编写了一个扩展类来帮助我从JSON源(字符串、流、文件)反序列化。

代码语言:javascript
复制
public static class JsonHelpers
{
    public static T CreateFromJsonStream<T>(this Stream stream)
    {
        JsonSerializer serializer = new JsonSerializer();
        T data;
        using (StreamReader streamReader = new StreamReader(stream))
        {
            data = (T)serializer.Deserialize(streamReader, typeof(T));
        }
        return data;
    }

    public static T CreateFromJsonString<T>(this String json)
    {
        T data;
        using (MemoryStream stream = new MemoryStream(System.Text.Encoding.Default.GetBytes(json)))
        {
            data = CreateFromJsonStream<T>(stream);
        }
        return data;
    }

    public static T CreateFromJsonFile<T>(this String fileName)
    {
        T data;
        using (FileStream fileStream = new FileStream(fileName, FileMode.Open))
        {
            data = CreateFromJsonStream<T>(fileStream);
        }
        return data;
    }
}

反序列化现在就像写代码一样简单:

代码语言:javascript
复制
MyType obj1 = aStream.CreateFromJsonStream<MyType>();
MyType obj2 = "{\"key\":\"value\"}".CreateFromJsonString<MyType>();
MyType obj3 = "data.json".CreateFromJsonFile<MyType>();

希望能对其他人有所帮助。

票数 32
EN

Stack Overflow用户

发布于 2014-02-25 06:39:16

我提出这个问题是为了寻找一种方法,将开放的对象列表流式传输到System.IO.Stream上,并从另一端读取它们,而不需要在发送之前缓冲整个列表。(具体地说,我通过Web API从MongoDB流式传输持久化对象。)

@Paul Tyng和@Rivers很好地回答了最初的问题,我使用他们的答案为我的问题建立了一个概念证明。我决定在这里发布我的测试控制台应用程序,以防其他人面临同样的问题。

代码语言:javascript
复制
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace TestJsonStream {
    class Program {
        static void Main(string[] args) {
            using(var writeStream = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None)) {
                string pipeHandle = writeStream.GetClientHandleAsString();
                var writeTask = Task.Run(() => {
                    using(var sw = new StreamWriter(writeStream))
                    using(var writer = new JsonTextWriter(sw)) {
                        var ser = new JsonSerializer();
                        writer.WriteStartArray();
                        for(int i = 0; i < 25; i++) {
                            ser.Serialize(writer, new DataItem { Item = i });
                            writer.Flush();
                            Thread.Sleep(500);
                        }
                        writer.WriteEnd();
                        writer.Flush();
                    }
                });
                var readTask = Task.Run(() => {
                    var sw = new Stopwatch();
                    sw.Start();
                    using(var readStream = new AnonymousPipeClientStream(pipeHandle))
                    using(var sr = new StreamReader(readStream))
                    using(var reader = new JsonTextReader(sr)) {
                        var ser = new JsonSerializer();
                        if(!reader.Read() || reader.TokenType != JsonToken.StartArray) {
                            throw new Exception("Expected start of array");
                        }
                        while(reader.Read()) {
                            if(reader.TokenType == JsonToken.EndArray) break;
                            var item = ser.Deserialize<DataItem>(reader);
                            Console.WriteLine("[{0}] Received item: {1}", sw.Elapsed, item);
                        }
                    }
                });
                Task.WaitAll(writeTask, readTask);
                writeStream.DisposeLocalCopyOfClientHandle();
            }
        }

        class DataItem {
            public int Item { get; set; }
            public override string ToString() {
                return string.Format("{{ Item = {0} }}", Item);
            }
        }
    }
}

请注意,当AnonymousPipeServerStream被释放时,您可能会收到异常,我忽略了这一点,因为它与当前的问题无关。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8157636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档