在2个配置文件之间传输值

本文关键字:传输 之间 配置文件 2个 | 更新日期: 2023-09-27 17:59:11

我有一个问题,我自己无法解决。。在我的程序中,我有一个自动更新程序,当我的程序更新一个新的(更改的,一些新的密钥)配置文件时,就会创建。我希望我的程序在更新时同时查看配置文件(旧的和新的),并将与新文件中的键匹配的旧设置传输到新文件。

这是旧文件的一个例子:

 {
  "Setting1": false,
  "Setting2": 123,
  "Setting3": "test",
  "LocationList": {
    "Country": "NL",
    "Locations": [
      {
        "Latitude": 38.556807486461118,
        "Longitude": -121.2383794784546
      },
      {
        "Latitude": -33.859019,
        "Longitude": 151.213098
      },
      {
        "Latitude": 47.5014969,
        "Longitude": -122.0959568
      },
      {
        "Latitude": 51.5025343,
        "Longitude": -0.2055027
      }
    ]
  }
}

这可以是新文件(也可以不同):

{
  "Setting1": null,
  "Setting2": null,
  "Setting3": "",
  "Setting4": ""
  "LocationList": {
    "Country": "",
    "Locations": [
      {
        "Latitude": null,
        "Longitude": null
      },
      {
        "Latitude": null,
        "Longitude": null
      }
    ]
  }
}

预期结果:

 {
  "Setting1": false,
  "Setting2": 123,
  "Setting3": "test",
  "Setting4": ""
  "LocationList": {
    "Country": "NL",
    "Locations": [
      {
        "Latitude": 38.556807486461118,
        "Longitude": -121.2383794784546
      },
      {
        "Latitude": -33.859019,
        "Longitude": 151.213098
      },
      {
        "Latitude": 47.5014969,
        "Longitude": -122.0959568
      },
      {
        "Latitude": 51.5025343,
        "Longitude": -0.2055027
      }
    ]
  }
}

首先,我研究了在c#中创建一个类并对其进行反序列化,然后,我得出结论,这是不可能的,因为我不知道配置会是什么样子。

其次,我认为使用动态会起作用,但事实并非如此,因为我不知道其中有任何键。我也不知道如何计算。

最后,我研究了使用regex是否可能,对我来说,这似乎是不可能的。。

有人能告诉我他们会怎么做吗?我不需要代码,只需要朝着正确的方向推动即可。

附言:我不想将两者结合在一起,当旧文件中有密钥但新文件中没有密钥时,不需要传输(只有列表会从旧文件中完全传输,当列表为空/填充在新文件中时也是如此)。

在2个配置文件之间传输值

如果你真的想在JSON中尝试一些东西,我只能推荐优秀的JSON.Net库来为你解析JSON。使用LINQ到JSON,您可以很容易地在旧的配置文件和新的配置文件之间以递归方式找到匹配的密钥,并简单地将值从一个复制到另一个

请参阅上的文档和一个小示例http://www.newtonsoft.com/json/help/html/LINQtoJSON.htm

简单地说,你可以在pseudoCode中这样做。显然,这不会是超级性能的,因为你会递归地遍历两个文件很多次,并且可以进行优化,但同时,除非你的配置文件是巨大的斑点,否则这不会对任何类型的现代硬件造成任何问题

//load both config files
//load the first token in original file and walk recursively
 //for each token try to match in the new file and write data if required using the same recursive technique to walk the other file

我不需要代码,只需要朝着正确的方向推动即可。

将您的配置存储在一个常规的App.config文件中,并利用System.Configuration。根据配置的复杂性,您可以使用现成的<appSettings>,也可以构建自己的配置部分和元素。它仍然比自定义配置更容易,而且不会出错。

事情太复杂了,不能仅仅为了使用另一种(文本)格式就开始发明轮子。即使你解决了当前的问题,也会有更多的问题,这些问题已经在System.Configration中得到了解决。。。

您可以在此处开始探索配置选项;无论如何,在你最喜欢的搜索引擎中定期搜索会起到作用。。。

好吧,在遇到一些麻烦后,我设法解决了它(谢谢@Louis)。

我就是这样做的:

        private static bool TransferConfig(string baseDir, ISession session)
        {
            //if (!session.LogicSettings.TransferConfigAndAuthOnUpdate)
            //    return false;
            var configDir = Path.Combine(baseDir, "Config");
            if (!Directory.Exists(configDir))
                return false;
            var oldConf = GetJObject(Path.Combine(configDir, "config.json.old"));
            var oldAuth = GetJObject(Path.Combine(configDir, "auth.json.old"));
            GlobalSettings.Load("");
            var newConf = GetJObject(Path.Combine(configDir, "config.json"));
            var newAuth = GetJObject(Path.Combine(configDir, "auth.json"));
            TransferJSON(oldConf, newConf);
            TransferJSON(oldAuth, newAuth);
            File.WriteAllText(Path.Combine(configDir, "config.json"), newConf.ToString());
            File.WriteAllText(Path.Combine(configDir, "auth.json"), newAuth.ToString());
            return true;
        }
        private static JObject GetJObject(string filePath)
        {
            return JObject.Parse(File.ReadAllText(filePath));
        }
        private static bool TransferJSON(JObject oldFile, JObject newFile)
        {
            try
            {
                foreach (var newProperty in newFile.Properties())
                    foreach (var oldProperty in oldFile.Properties())
                        if (newProperty.Name.Equals(oldProperty.Name))
                        {
                            newFile[newProperty.Name] = oldProperty.Value;
                            break;
                        }
                return true;
            }
            catch
            {
                return false;
            }
        }