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

9 浏览
0 Comments

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

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

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

例如,在WinPhone上反序列化包含JSON的文件时,我使用以下代码将文件内容读入字符串,然后再反序列化成JSON。根据我的(非常临时的)测试,这个过程比直接从流中反序列化使用DataContractJsonSerializer要慢大约4倍...

// 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(json);

我做错了吗?

0
0 Comments

问题出现的原因是Json.NET在当前版本中不再支持直接将流序列化/反序列化为Json。解决方法是使用JsonTextReader类与StreamReader一起使用,或者直接使用接受StreamReader参数的JsonSerializer重载方法进行序列化/反序列化操作。

以下是解决方法的代码示例:

var serializer = new JsonSerializer();
serializer.Deserialize(streamReader);

这个方法已经过时,现在需要使用JsonReader或TextReader进行操作。

感谢您花时间编辑您的答案并提供工作状态和答案建议。

“不需要投票,这在旧版本中是正确的”-这个答案对大多数人来说已经不再相关,因此应该被投票为更好的答案。

0
0 Comments

问题的出现原因是:在将一个非常大的对象集合序列化为字符串,然后将该字符串写入流中时,会导致OutOfMemoryException异常。解决方法是直接将对象序列化到流中,而不是先序列化为字符串再写入流中。

代码中的Serialize方法将对象序列化到流中,Deserialize方法从流中反序列化对象。在序列化过程中,使用StreamWriter将流包装为JsonTextWriter,然后使用JsonSerializer进行序列化操作。在反序列化过程中,同样使用StreamReader将流包装为JsonTextReader,然后使用JsonSerializer进行反序列化操作。

代码中使用using块来确保在操作完成后正确释放资源。在序列化过程中,使用Flush()方法将缓冲区中的数据写入流中。问为什么要调用Flush()方法,因为using块会自动调用Dispose()方法,而Dispose()方法会自动调用Flush()方法,所以是否需要手动调用Flush()方法呢?有人回答说,由于之前遇到过这个问题,为了保险起见,习惯上手动调用Flush()方法。

另外,代码中还提到了一个有助于其他人的提示:如果使用JsonSerializer.Create(settings)方法,可以定义在序列化和反序列化过程中使用的设置。另外,Serialize方法的一个潜在问题是它会关闭传入的流,这在某些应用程序中可能会导致问题。在.NET 4.5及以上版本中,可以通过使用具有leaveOpen参数的StreamWriter构造函数重载来解决这个问题,该参数允许保持流处于打开状态。

以上代码提供了一种在Json.NET中将对象序列化到流中和从流中反序列化对象的方法,并解决了在序列化过程中可能出现的OutOfMemoryException异常的问题。

0
0 Comments

Json.NET是一个用于序列化和反序列化JSON数据的流行库。然而,当前版本的Json.NET不允许直接将JSON数据序列化/反序列化到/从流中。这个问题的解决方法是使用一个替代的代码块来实现这个功能。

下面是一个可以从流中反序列化JSON数据的替代方法的示例代码:

public static object DeserializeFromStream(Stream stream)
{
    var serializer = new JsonSerializer();
    using (var sr = new StreamReader(stream))
    using (var jsonTextReader = new JsonTextReader(sr))
    {
        return serializer.Deserialize(jsonTextReader);
    }
}

这段代码使用了Json.NET的JsonSerializer类来进行反序列化操作。它通过创建一个StreamReader来读取流中的内容,并将StreamReader传递给JsonTextReader,最后使用JsonSerializer的Deserialize方法来进行反序列化。

需要注意的是,JsonTextReader会默认关闭它的StreamReader,所以可以在JsonTextReader的构造函数中直接传递StreamReader,从而简化代码。

然而,一些用户在使用这段代码时遇到了OutOfMemory异常,尤其是在32位进程中反序列化大型对象时。这是因为在32位进程中,可用的内存空间有限。为了解决这个问题,可以尝试优化代码或使用更高版本的Json.NET。

此外,有用户报告说在使用JsonTextReader时遇到了"The type or namespace name 'JsonTextReader' could not be found"的错误。这可能是因为没有正确引用Json.NET库。需要确保已正确引用Json.NET库并在代码中导入相应的命名空间。

还有用户提到需要在反序列化之前将流的位置重置为0,以确保正确反序列化JSON数据。可以使用stream.Position = 0;来实现。

需要注意的是,给出的链接中的文档并没有提到JsonTextReader,所以有用户对此感到困惑。如果需要控制序列化器的设置,可以使用JsonSerializer.Create();方法来代替构造函数。

最后,有用户询问是否有一个使用异步读取流的版本。目前,Json.NET没有内置的异步读取流的功能,但可以使用.NET的异步编程模型(APM)或使用第三方库来实现异步读取流的操作。

总之,虽然当前版本的Json.NET不直接支持将JSON数据序列化/反序列化到/从流中,但可以使用替代的代码块来实现这个功能。需要注意的是,根据特定的情况可能会遇到一些问题,例如内存限制或引用错误。为了解决这些问题,可以尝试优化代码、升级Json.NET版本或使用其他库来实现特定的需求,如异步读取流。

0