在 C# 中读取和写入 INI 文件

Muhammad Zeeshan 2023年10月12日
  1. C# 中的 INI 文件是什么
  2. C# 中使用 WritePrivateProfileString 来保存 INI 文件中新的和修改的设置
  3. C# 中使用 ReadPrivateProfileString 从一个 INI 文件中读取数据
  4. C# 中读取和写入 INI 文件
在 C# 中读取和写入 INI 文件

本教程教授如何在 C# 中读取和写入 INI 文件。

C# 中的 INI 文件是什么

初始化文件,通常称为 INI 文件,是用于存储程序配置信息的文本文件。 .NET 框架本身不支持 INI 文件。

你可以利用 Windows API 方法使用平台调用服务来写入和读取文件。本教程将构建一个表示 INI 文件的类,并使用 Windows API 操作来操作它们。

要使用 INI 文件,我们需要两个 Windows API 函数,WritePrivateProfileStringReadPrivateProfileString

C# 中使用 WritePrivateProfileString 来保存 INI 文件中新的和修改的设置

INI 文件中,WritePrivateProfileString 保存新的和修改的设置。结构如下。

bool WritePrivateProfileString(string name, string key, string value, string filepath);

如果写入成功,则该函数返回布尔结果,如果写入失败,则返回 false。以下是参数。

  1. 要写入的部分名称由 name 指定。
  2. 要设置的键名由 key 指定。
  3. 键的值由 value 指定。
  4. filepath 保存要更新的 INI 文件的位置。

C# 中使用 ReadPrivateProfileString 从一个 INI 文件中读取数据

ReadPrivateProfileStringINI 文件中读取数据。该函数根据其应用程序读取单个值、节中的所有键名或所有部分的名称。

int GetPrivateProfileString(string name, string key, string default, StringBuilder ReturnedVal,
                            int maxsize, string filepath);

函数将返回值中的字符数作为无符号整数返回。以下是参数。

  1. 要读取的部分名称由 name 指定。如果将其设置为 null,则将返回所有部分名称。
  2. 要读取的键名由 key 指定。如果设置为 null 而 name 不为 null,则返回的值将包括给定部分中键的名称。
  3. 如果键不存在,default 指定要返回的默认值。
  4. ReturnedVal 接收用作缓冲区的字符串。操作的结果被写入缓冲区,修改字符串的值。
  5. ReturnedVal 中将返回的字符串的最大大小由 maxsize 指定。这应该与缓冲区大小相同。如果从 INI 文件中读取的值比 ReturnedVal 长,它将被减少。
  6. 要读取的 INI 文件的位置和名称由 filepath 指定。该文件必须存在。

C# 中读取和写入 INI 文件

让我们创建一个类来保存我们将使用的 Windows API 函数的结构,因为我们已经看到了它们的结构。

添加以下库。

using System;
using System.IO;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;

创建一个名为 ReadWriteINIfile 的新类并使用以下类代码。因为类本身没有访问修饰符,所以它会有一个内部作用域。

IniFile 类将访问 API 函数而不将它们暴露给公众。

public class ReadWriteINIfile {
  [DllImport("kernel32")]
  private static extern long WritePrivateProfileString(string name, string key, string val,
                                                       string filePath);
  [DllImport("kernel32")]
  private static extern int GetPrivateProfileString(string section, string key, string def,
                                                    StringBuilder retVal, int size,
                                                    string filePath);
}

我们现在可以构造 ReadWriteINIfile 类,允许我们在不知道 API 操作的情况下读取 INI 文件。

将以下代码添加到类以创建构造函数。

public ReadWriteINIfile(string inipath) {
  path = inipath;
}

WritePrivateProfileString 用于用值填充 INI 文件。下面的代码中使用了三个参数来接受节和键名以及要保存的值。

在对 WritePrivateProfileString 的调用中,这些值与传递给构造函数的文件名组合在一起。

public void WriteINI(string name, string key, string value) {
  WritePrivateProfileString(name, key, value, this.path);
}

ReadINI 的参数是要读取的 namekey。上面代码的第一行定义了字符串并将其值设置为几个等于其最大长度的空格。

GetPrivateProfileString 函数接收此字符串作为要填充的缓冲区。使用下面的代码。

public string ReadINI(string name, string key) {
  StringBuilder sb = new StringBuilder(255);
  int ini = GetPrivateProfileString(name, key, "", sb, 255, this.path);
  return sb.ToString();
}

完整源代码:

using System;
using System.IO;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;

namespace Test {
  class Program {
    static void Main(string[] args) {}
  }
  public class ReadWriteINIfile {
    [DllImport("kernel32")]
    private static extern long WritePrivateProfileString(string name, string key, string val,
                                                         string filePath);
    [DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section, string key, string def,
                                                      StringBuilder retVal, int size,
                                                      string filePath);

    public string path;

    public ReadWriteINIfile(string inipath) {
      path = inipath;
    }
    public void WriteINI(string name, string key, string value) {
      WritePrivateProfileString(name, key, value, this.path);
    }
    public string ReadINI(string name, string key) {
      StringBuilder sb = new StringBuilder(255);
      int ini = GetPrivateProfileString(name, key, "", sb, 255, this.path);
      return sb.ToString();
    }
  }
}
Muhammad Zeeshan avatar Muhammad Zeeshan avatar

I have been working as a Flutter app developer for a year now. Firebase and SQLite have been crucial in the development of my android apps. I have experience with C#, Windows Form Based C#, C, Java, PHP on WampServer, and HTML/CSS on MYSQL, and I have authored articles on their theory and issue solving. I'm a senior in an undergraduate program for a bachelor's degree in Information Technology.

LinkedIn