如何使用JSON.NET保存带有四个空格缩进的JSON文件?

时间:2014-09-11 13:25:43

标签: c# .net json json.net

我需要读取JSON配置文件,修改值,然后再次将修改后的JSON保存回文件。 JSON非常简单:

{
    "test": "init",
    "revision": 0
}

要加载数据并修改值,我这样做:

var config = JObject.Parse(File.ReadAllText("config.json"));
config["revision"] = 1;

到目前为止一切顺利;现在,将JSON写回文件。首先我尝试了这个:

File.WriteAllText("config.json", config.ToString(Formatting.Indented));

正确写入文件,但缩进只有两个空格。

{
  "test": "init",
  "revision": 1
}

从文档中看,似乎没有办法以这种方式传递任何其他选项,因此我尝试修改this example,这样我就可以直接设置IndentationIndentChar JsonTextWriter的属性,用于指定缩进量:

using (FileStream fs = File.Open("config.json", FileMode.OpenOrCreate))
{
    using (StreamWriter sw = new StreamWriter(fs))
    {
        using (JsonTextWriter jw = new JsonTextWriter(sw))
        {
            jw.Formatting = Formatting.Indented;
            jw.IndentChar = ' ';
            jw.Indentation = 4;

            jw.WriteRaw(config.ToString());
        }
    }
}

但这似乎没有任何影响:文件仍然写有两个空格缩进。我做错了什么?

4 个答案:

答案 0 :(得分:13)

问题是您正在使用config.ToString(),因此当您使用JsonTextWriter编写对象时,该对象已经被序列化为字符串并进行格式化。

使用序列化器将对象序列化到编写器:

JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(jw, config);

答案 1 :(得分:0)

也许尝试将标签字符输入IndentChar?

...    
jw.IndentChar = '\t';
...

根据文档,它应该使用制表符来缩进JSON而不是空格字符。 http://james.newtonking.com/json/help/index.html?topic=html/T_Newtonsoft_Json_Formatting.htm

答案 2 :(得分:0)

我遇到了同样的问题,发现WriteRaw不会影响缩进设置,但是您可以在JObject上使用WriteTo来解决该问题

using (FileStream fs = File.Open("config.json", FileMode.OpenOrCreate))
{
    using (StreamWriter sw = new StreamWriter(fs))
    {
        using (JsonTextWriter jw = new JsonTextWriter(sw))
        {
            jw.Formatting = Formatting.Indented;
            jw.IndentChar = ' ';
            jw.Indentation = 4;

            config.WriteTo(jw);
        }
    }
}

答案 3 :(得分:0)

这里有一个扩展方法,它使 json 易于人类阅读。 它删除属性名称中的引号,将枚举转换为字符串并使用 4 个空格缩进 json。

public static string ToPrettyJson(this object obj)
{
    var json = JsonConvert.SerializeObject(obj, Formatting.Indented, new StringEnumConverter());
    json = Regex.Replace(json, @"^([\s]+)""([^""]+)"": ", "$1$2: ", RegexOptions.Multiline); // no quotes in props
    json = Regex.Replace(json, @"^[ ]+", m => new String(' ', m.Value.Length * 2), RegexOptions.Multiline); // more indent spaces
    return json;
}