首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 讀寫 INI 檔案:P/Invoke 封裝 GetPrivateProfileString 與 WritePrivateProfileString

     編輯:關於C#

為什麼還需要 INI?

  • 相容舊系統/嵌入式裝置設定檔
  • 簡單鍵值對,無 XML/JSON 解析開銷
  • 原生 Windows API 支援,無額外依賴

Windows API 簽名


using System;
using System.Runtime.InteropServices;
using System.Text;

public static class IniFile
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetPrivateProfileString(
        string lpAppName,     // Section
        string lpKeyName,     // Key
        string lpDefault,     // Default value
        StringBuilder lpReturnedString, // Buffer
        int nSize,            // Buffer size
        string lpFileName);   // INI file path

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int WritePrivateProfileString(
        string lpAppName,     // Section
        string lpKeyName,     // Key
        string lpString,      // Value (null = delete key)
        string lpFileName);   // INI file path

封裝方法


    private const int BufferSize = 1024;

    /// 
    /// 讀取值
    /// 
    public static string Read(string section, string key, string defaultValue, string filePath)
    {
        var sb = new StringBuilder(BufferSize);
        GetPrivateProfileString(section, key, defaultValue, sb, BufferSize, filePath);
        return sb.ToString();
    }

    /// 
    /// 寫入值 (value=null 刪除鍵)
    /// 
    public static void Write(string section, string key, string value, string filePath)
    {
        WritePrivateProfileString(section, key, value, filePath);
    }

    /// 
    /// 刪除整個 Section
    /// 
    public static void DeleteSection(string section, string filePath)
    {
        WritePrivateProfileString(section, null, null, filePath);
    }

    /// 
    /// 讀取 Section 所有 Key
    /// 
    public static string[] ReadAllKeys(string section, string filePath)
    {
        var sb = new StringBuilder(BufferSize * 10);
        GetPrivateProfileString(section, null, "", sb, sb.Capacity, filePath);
        return sb.ToString().Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
    }

    /// 
    /// 讀取 Section 所有 Key-Value
    /// 
    public static Dictionary ReadSection(string section, string filePath)
    {
        var dict = new Dictionary();
        var keys = ReadAllKeys(section, filePath);
        foreach (var key in keys)
            dict[key] = Read(section, key, "", filePath);
        return dict;
    }
}

使用範例


var iniPath = @"C:\Config\app.ini";

// 寫入
IniFile.Write("Database", "Host", "localhost", iniPath);
IniFile.Write("Database", "Port", "5432", iniPath);
IniFile.Write("Database", "User", "admin", iniPath);
IniFile.Write("App", "Version", "1.2.3", iniPath);

// 讀取
string host = IniFile.Read("Database", "Host", "127.0.0.1", iniPath);
int port = int.Parse(IniFile.Read("Database", "Port", "5432", iniPath));

// 列出 Section
var dbSettings = IniFile.ReadSection("Database", iniPath);
foreach (var kv in dbSettings)
    Console.WriteLine($"{kv.Key} = {kv.Value}");

// 刪除 Key
IniFile.Write("Database", "User", null, iniPath);

// 刪除 Section
IniFile.DeleteSection("App", iniPath);

產生的 INI 檔案內容


[Database]
Host=localhost
Port=5432
User=admin

[App]
Version=1.2.3

進階:強型別包裝類別


public class AppSettings
{
    private readonly string _path;
    public AppSettings(string path) => _path = path;

    public string DbHost 
    { 
        get => IniFile.Read("Database", "Host", "localhost", _path);
        set => IniFile.Write("Database", "Host", value, _path);
    }
    
    public int DbPort 
    { 
        get => int.Parse(IniFile.Read("Database", "Port", "5432", _path));
        set => IniFile.Write("Database", "Port", value.ToString(), _path);
    }
    
    public string Version 
    { 
        get => IniFile.Read("App", "Version", "1.0.0", _path);
        set => IniFile.Write("App", "Version", value, _path);
    }
}

注意事項與限制

項目說明
編碼ANSI (系統預設代碼頁),Unicode 需自行處理 (寫入 UTF-16 LE + BOM 並用 Wide 版 API)
長度限制單值 32KB (API 限制),Section/Key 名稱 255 字元
效能每次呼叫都開啟/關閉檔案,頻繁存取建議快取或改用 XML/JSON
並發多進程寫入可能衝突,需外部鎖 (Mutex) 保護
跨平台僅限 Windows (kernel32.dll),.NET Core 跨平台專案請改用 Microsoft.Extensions.Configuration.Ini

.NET Core / 5+ 現代替代方案


// NuGet: Microsoft.Extensions.Configuration.Ini
using Microsoft.Extensions.Configuration;

var config = new ConfigurationBuilder()
    .AddIniFile("appsettings.ini", optional: false, reloadOnChange: true)
    .Build();

string host = config["Database:Host"]; // 以冒號分隔 Section:Key
int port = config.GetValue("Database:Port");

P/Invoke 封裝 Windows INI API 簡單直接,適合維護舊專案或輕量原生需求;新專案建議採用現代 Configuration 抽象層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved