C# ReadAllTextFile与StreamReader用于JSON解析

C# ReadAllTextFile与StreamReader用于JSON解析,c#,json,io,json.net,C#,Json,Io,Json.net,这更多的是一个理论问题,但我很好奇这两种读取文件的方法之间的区别是什么,以及为什么我会选择其中一种而不是另一种 我正在解析一个JSON配置文件(来自本地磁盘)。以下是一种方法: // Uses JSON.NET Serializer + StreamReader using(var s = new StreamReader(file)) { var jtr = new JsonTextReader(sr); var jsonSerializer = new JsonSerializer(

这更多的是一个理论问题,但我很好奇这两种读取文件的方法之间的区别是什么,以及为什么我会选择其中一种而不是另一种

我正在解析一个JSON配置文件(来自本地磁盘)。以下是一种方法:

// Uses JSON.NET Serializer + StreamReader
using(var s = new StreamReader(file))
{
  var jtr = new JsonTextReader(sr);
  var jsonSerializer = new JsonSerializer();
  return jsonSerializer.Deserialize<Configuration>(jtr);
}
//使用JSON.NET序列化程序+StreamReader
使用(var s=新的StreamReader(文件))
{
var jtr=新的JsonTextReader(sr);
var jsonSerializer=新的jsonSerializer();
返回jsonSerializer.Deserialize(jtr);
}
…第二种选择

// Reads the entire file and deserializes.
var json = File.ReadAllText(file);
return JsonConvert.DeserializeObject<JsonVmrConfigurationProvider>(json);
//读取整个文件并反序列化。
var json=File.ReadAllText(文件);
返回JsonConvert.DeserializeObject(json);
一个比另一个好吗?是否有一种情况下应该使用其中一种


再一次,这是理论上的,但是,我意识到我真的不知道答案,而且在线搜索并没有产生令我满意的结果。我可以看到第二个是坏的,如果该文件是大的(它不是),因为它被读取到内存中的一个镜头。还有其他原因吗?

通过阅读代码,您发现字符串的反序列化最终达到:

public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
    {
        ValidationUtils.ArgumentNotNull(value, "value");

        JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);

        // by default DeserializeObject should check for additional content
        if (!jsonSerializer.IsCheckAdditionalContentSet())
            jsonSerializer.CheckAdditionalContent = true;

        using (var reader = new JsonTextReader(new StringReader(value)))
        {
            return jsonSerializer.Deserialize(reader, type);
        }
    }
这是一个JsonTextReader的创建

因此,两者的区别似乎在于如何有效地处理大型文件

--先前的评论:

JsonTextReader重写JsonReader.Close()并处理流(如果CloseInput为true),但不仅仅是


默认情况下,CloseInput应该为true,因为StringReader没有在前面的代码片段中显式地释放,而
File.ReadAllText()
,在反序列化之前,需要先将整个JSON加载到内存中。使用
StreamReader
,以增量方式读取和反序列化文件。因此,如果您的文件很大,您可能希望使用
StreamReader
来避免将整个文件加载到内存中。如果您的JSON文件很小(大多数情况下),它实际上没有什么区别。

我可以看到,第一个文件可能会将文本流式传输到反序列化程序,而不是预先一次加载所有文本。在JSON非常大的情况下,这将具有更好的内存特性。这一切都取决于Json.net的实现。可能是第二种方法可以防止您忘记处理JsonTextReader吗?:)@tschmit007:由于可能只有一个可使用的资源(打开的文件),第二个dispose可能是多余的。对于类似的BCL结构,双重使用fire CA2202警告正是出于这个原因。这有点让人困惑。。。我惊讶地看到CA2202弹出。看这个问题:好吧,阅读Close方法,读者似乎并不关心流。但从同一个来源,我会说可能没有泄漏(取决于_值的实际有效类型)。无论如何,谢谢您的CA2202:)