【问题标题】:reading external configuration file读取外部配置文件
【发布时间】:2023-03-07 05:40:02
【问题描述】:

我有一个执行 FTP 操作的 c# .Net 控制台应用程序。 目前,我在自定义配置部分中指定设置,例如

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="ftpConfiguration" type="FileTransferHelper.FtpLibrary.FtpConfigurationSection, FileTransferHelper.FtpLibrary" />
  </configSections>

  <ftpConfiguration>
      <Environment name="QA">
        <sourceServer hostname="QA_hostname"
                      username="QA_username"
                      password="QA_password"
                      port="21"
                      remoteDirectory ="QA_remoteDirectory" />
        <targetServer downloadDirectory ="QA_downloadDirectory" />

      </Environment>
  </ftpConfiguration>

</configuration>

我想在命令行中指定一个外部配置文件。

但是!!!...

我刚刚意识到上面的“FtpConfiguration”部分并不真正属于应用程序的 app.config。我的最终目标是我将有许多计划任务来执行我的控制台应用程序,如下所示:

FileTransferHelper.exe -c FtpApplication1.config
FileTransferHelper.exe -c FtpApplication2.config
...
FileTransferHelper.exe -c FtpApplication99.config

因此,我相信我走错了路,我真正想要的是在我的自定义 xml 文档中读取一些内容,但继续使用 System.Configuration 来获取值...而不是读取 XmlDocument 和序列化它以获取节点/元素/属性。 (不过,如果有人可以给我看一些简单的代码,我不反对后者)

指针将不胜感激。谢谢。

更新: 我接受的答案是指向另一个 StackOverflow 问题的链接,在这里用我的代码重复 - 下面正是我正在寻找的 - 使用 OpenMappedExeConfiguration 打开我的外部配置文件

ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = @"D:\Development\FileTransferHelper\Configuration\SampleInterface.config";

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);

FtpConfigurationSection ftpConfig = (FtpConfigurationSection)config.GetSection("ftpConfiguration");

【问题讨论】:

  • 请注意,如果您决定只解析 xml:XmlDocument 是在 C# 中处理 xml 的旧方法,虽然您当然可以这样做,但我建议使用 XDocument,它是Linq 到 XML。

标签: c# configuration system.configuration


【解决方案1】:

如果您想使用 System.Configuration 打开您的自定义文件,您可能需要查看此帖子:Loading custom configuration files。 Oliver 以一种非常直接的方式指出了这一点。

由于您想读取通过命令行传递给应用程序的参数,您可能需要访问此 MSDN 帖子:Command Line Parameters Tutorial

如果您更愿意使用自定义方法,有几种方法可以实现。一种可能性是实现一个加载器类,并使用您的自定义配置文件。

例如,让我们假设一个简单的配置文件如下所示:

spec1.config

<?xml version="1.0" encoding="utf-8"?>
<Settings>
    <add key="hostname" value="QA_hostname" />
    <add key="username" value="QA_username" />
</Settings>

一个非常简单的类似哈希表的(键值对)结构。

一个已实现的解析器/读取器将如下所示:

        private Hashtable getSettings(string path)
        {
            Hashtable _ret = new Hashtable();
            if (File.Exists(path))
            {
                StreamReader reader = new StreamReader
                (
                    new FileStream(
                        path,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read)
                );
                XmlDocument doc = new XmlDocument();
                string xmlIn = reader.ReadToEnd();
                reader.Close();
                doc.LoadXml(xmlIn);
                foreach (XmlNode child in doc.ChildNodes)
                    if (child.Name.Equals("Settings"))
                        foreach (XmlNode node in child.ChildNodes)
                            if (node.Name.Equals("add"))
                                _ret.Add
                                (
                                    node.Attributes["key"].Value,
                                    node.Attributes["value"].Value
                                );
            }
            return (_ret);
        }

同时,您仍然可以使用ConfigurationManager.AppSettings[] 读取原始app.config 文件。

【讨论】:

    【解决方案2】:

    如果您使用自定义路径,老实说,我只会使用 JSON 来存储配置,然后反序列化以加载它并序列化以编写它。 Json.NET 让你可以很轻松地做到这一点。

    您的 XML:

    <ftpConfiguration>
      <Environment name="QA">
        <sourceServer hostname="QA_hostname"
                      username="QA_username"
                      password="QA_password"
                      port="21"
                      remoteDirectory ="QA_remoteDirectory" />
        <targetServer downloadDirectory ="QA_downloadDirectory" />
    
      </Environment>
    </ftpConfiguration>
    

    在 JSON 中看起来像这样:

    {
      "FtpConfiguration": {
        "Environment": {
          "Name": "QA",
          "SourceServer": {
            "HostName": "QA_hostname",
            "UserName": "QA_username",
            "Password": "QA_password",
            "Port": "21",
            "RemoteDirectory": "QA_remoteDirectory"
          },
          "TargetServer": {
            "DownloadDirectory": "QA_downloadDirectory"
          }
        }
      }
    }
    

    您的课程如下所示:

    class Config
    {
        public FtpConfiguration FtpConfiguration { get; set; }
    }
    
    class FtpConfiguration
    {
        public Environment Environment { get; set; }
    }
    
    class Environment
    {
        public SourceServer SourceServer { get; set; }
        public TargetServer TargetServer { get; set; }
    }
    
    class SourceServer
    {
        public string HostName { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public int Port { get; set; }
        public string RemoteDirectory { get; set; }
    }
    
    class TargetServer
    {
        public string DownloadDirectory { get; set; }
    }
    

    您可以将设置保存到这样的对象中:

    var config = new Config()
    {
        FtpConfiguration = new FtpConfiguration()
        {
            Environment = new Environment()
            {
                SourceServer = new SourceServer()
                {
                    HostName = "localhost",
                    UserName = "jaxrtech",
                    Password = "stackoverflowiscool",
                    Port = 9090,
                    RemoteDirectory = "/data",
                },
                TargetServer = new TargetServer()
                {
                    DownloadDirectory = "/downloads"
                }
            }
        }
    };
    

    然后您可以像这样写入文件(如果文件更大,则使用Stream):

    string json = JsonConvert.SerializeObject(config);
    File.WriteAllText("config.json", json);
    

    然后您可以像这样读取文件(同样您可以使用Stream):

    string json = File.ReadAllText("config.json");
    Config config = JsonConvert.DeserializeObject<Config>(json);
    

    【讨论】:

      【解决方案3】:

      我首选的解决方案使用 XDocument。我还没有测试过,所以可能会有一些小问题,但这是为了证明我的观点。

      public Dictionary<string, string> GetSettings(string path)
      {
      
        var document = XDocument.Load(path);
      
        var root = document.Root;
        var results =
          root
            .Elements()
            .ToDictionary(element => element.Name.ToString(), element => element.Value);
      
        return results;
      
      }
      

      将返回一个字典,其中包含表单的 xml 中的元素名称和值:

      <?xml version="1.0" encoding="utf-8"?>
      <root>
        <hostname>QA_hostname</hostname>
        <username>QA_username</username>
      </root>
      

      我觉得这个解决方案很好,因为它整体简洁。

      同样,我不希望它完全按原样工作。使用 XAttributes 和 XElements 等,你绝对可以让它更像你的原版。这将很容易过滤。

      【讨论】:

      • @OnoSendai:这确实是我最喜欢的 Linq 部分之一,我认为很多人都没有意识到它甚至在那里。我想它是相对较新的。不过,命名空间的工作方式可能有点令人困惑。
      • 这是我最喜欢的解决方案,清晰、锐利且不占用 CPU。我不知道这是否比其他更快,我会尝试。
      猜你喜欢
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2020-11-18
      • 2016-01-11
      • 2013-01-07
      • 2021-05-30
      • 2016-10-29
      • 2013-04-15
      相关资源
      最近更新 更多