如何修改JSON格式化文件?

时间:2012-04-07 09:22:42

标签: c# .net json

我想要做的是从Google Chrome浏览器的Preferences文件中更改两个值。我现在使用的代码如下

[DataContract]
public class Mdata
{
    [DataMember(Name = "homepage")]
    public String homepage { get; private set; }
    [DataMember(Name = "homepage_is_newtabpage")]
    public Boolean isNewTab { get; private set; }
    [DataMember(Name = "keep_everything_synced")]
    public Boolean isSynced { get; private set; }
    public Mdata() { }
    public Mdata(String data)
    {
        homepage = data;
    }
}

public static Mdata FindData(String json)
{
    Mdata deserializedData = new Mdata();
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
    DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedData.GetType());
    deserializedData = ser.ReadObject(ms) as Mdata;
    ms.Close();
    return deserializedData;
}

private void button1_Click(object sender, EventArgs e)
{
    const int LikeWin7 = 6;
    OperatingSystem osInfo = Environment.OSVersion;
    DirectoryInfo strDirectory;
    String path = null, file = null, data;

    if (osInfo.Platform.Equals(System.PlatformID.Win32NT))
        if (osInfo.Version.Major == LikeWin7)
            path = Environment.GetEnvironmentVariable("LocalAppData") +
                @"\Google\Chrome\User Data\Default";
    if (path == null || path.Length == 0)
        throw new ArgumentNullException("Fail. Bad OS.");
    if (!(strDirectory = new DirectoryInfo(path)).Exists)
        throw new DirectoryNotFoundException("Fail. The directory was not fund");
    if (!new FileInfo(file = Directory.GetFiles(strDirectory.FullName, "Preferences*")[0]).Exists)
        throw new FileNotFoundException("Fail. The file was not found.", file);

    Mdata info = FindData(data = System.IO.File.ReadAllText(file));
    Console.WriteLine(info.homepage); // show me http://www.google.com
    Console.WriteLine(info.isNewTab); // prints false
    MessageBox.Show(info.isSynced); // prints true
    }

我现在要做的是将info.homepage,info.isNewTab和info.isSynced的值更改为其他值,如(在首选项文件中):

"homepage": "http://www.myWebsite.com/",
"homepage_is_newtabpage": true,
...
"keep_everything_synced": false,

我试图直接设置像这样的新值:

 info.homepage = "www.mysite.com";
 info.isNewTab = true;
 info.isSynced = false;

但没有机会!

如何为上面的三个对象分配新值?

2 个答案:

答案 0 :(得分:2)

您发布的代码有两个问题:

  1. 您永远不会将数据写回磁盘。
  2. 您只映射了您感兴趣的三个属性。这意味着只有那些将被反序列化。当您更改它们并将其写回磁盘时,只会将这些属性序列化,因为所有其他数据都没有进入您的数据结构。
  3. 您的问题有几种可能的解决方案:

    1. 完全映射Mdata结构中的首选项文件。由于首选项文件非常大,这显然有点痛苦。
    2. this question的已接受答案显示了如何将任意JSON对象/序列化为字典。
    3. 根本不要使用JSON反序列化。只需打开文件逐行读取它并使用正则表达式来匹配您想要的设置。找到值时替换该值。并将每一行写回(修改或未修改)。

答案 1 :(得分:1)

一旦你有了反序列化的对象,就像你在这里所做的那样:

Mdata info = FindData(data = System.IO.File.ReadAllText(file));

将您想要的值分配给这些属性:

 info.homepage = "www.mysite.com";
 info.isNewTab = true;
 info.isSynced = false;

然后将对象序列化回文件,覆盖它。 这是缺失的位 - 您永远不会将更改beck写入磁盘。

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Mdata));
using(var fs = new FileStream(filePath, FileMode.Create)
{
  ser.WriteObject(fs, info);
}