C# 读取外部配置文件

C# 读取外部配置文件,c#,configuration,system.configuration,C#,Configuration,System.configuration,我有一个c#.Net控制台应用程序,可以执行FTP操作。 目前,我在自定义配置部分指定设置,例如 <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="ftpConfiguration" type="FileTransferHelper.FtpLibrary.FtpConfigurationSection, FileTra

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

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

如有指点,将不胜感激。谢谢

更新: 我接受的答案是一个指向另一个StackOverflow问题的链接,这里用我的代码重复了这个问题——下面就是我要找的——使用OpenMapdexeConfiguration打开我的外部配置文件

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");

如果您想使用System.Configuration打开您的自定义文件,您可能需要查看以下帖子:。奥利弗用一种非常直截了当的方式完成了这件事

由于您希望读取通过命令行传递给应用程序的参数,因此您可能希望访问此MSDN帖子:

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

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

FileTransferHelper.exe -c FtpApplication1.config
FileTransferHelper.exe -c FtpApplication2.config
...
FileTransferHelper.exe -c FtpApplication99.config
        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);
        }
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"
            }
        }
    }
};
spec1.config

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

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

我的首选解决方案使用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;

}
公共字典设置(字符串路径)
{
var document=XDocument.Load(路径);
var root=document.root;
var结果=
根
.要素()
.ToDictionary(element=>element.Name.ToString(),element=>element.Value);
返回结果;
}
将返回一个字典,其中包含表单xml中的元素名称和值:

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

QA_主机名
QA_用户名
我觉得这个解决方案很好,因为它总体上很简洁


再说一次,我不希望这一切完全照旧。使用XAttributes和XElements等,您肯定可以使其更像您的原创作品。它将很容易过滤。

如果您选择自定义路径,我会诚实地使用JSON存储配置,然后反序列化以加载它,并序列化以编写它。允许您非常轻松地执行此操作

您的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>
您的类将如下所示:

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; }
}
您可以将设置保存到如下对象中:

FileTransferHelper.exe -c FtpApplication1.config
FileTransferHelper.exe -c FtpApplication2.config
...
FileTransferHelper.exe -c FtpApplication99.config
        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);
        }
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"
            }
        }
    }
};
然后,您可以像这样写入文件(如果文件较大,则使用
):

然后可以像这样读取文件(同样可以使用
流来代替):

string json=File.ReadAllText(“config.json”);
Config=JsonConvert.DeserializeObject(json);

请注意,如果您决定只解析xml:XmlDocument是C#中处理xml的旧方法,虽然您当然可以这样做,但我建议您使用XDocument,它是Linq to xml的一部分。@OnoSendai:这确实是我最喜欢的Linq部分之一,我想很多人都没有意识到它的存在。不过,我想这是相对较新的。不过,名称空间的工作方式可能有点混乱。这是我最喜欢的解决方案,它清晰、清晰,而且不需要占用CPU太多精力。我不知道这是否比其他的快,我会在将来尝试。