C# ini文件操作类

C# ini文件操作类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;

namespace getini
{
    public class IniGet
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);


        [DllImport("kernel32")]
        private static extern int WritePrivateProfileStringA(string lpAppName, string lpKeyName, string lpString, string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);

        private string ReadString(string section, string key, string def, string filePath)
        {
            StringBuilder temp = new StringBuilder(1024);

            try
            {
                GetPrivateProfileString(section, key, def, temp, 1024, filePath);
            }
            catch
            { }
            return temp.ToString();
        }

        public void INIWrite(string section, string key, string value, string path)
        {
            // section=配置节点名称,key=键名,value=返回键值,path=路径
            WritePrivateProfileString(section, key, value, path);
        }

        public Dictionary<string, string> ReadIniAllKeys(string section, string filePath)
        {
            UInt32 MAX_BUFFER = 32767;

            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            string[] items = new string[0];

            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));

            UInt32 bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, filePath);

            if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
            {
                string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);

                items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
            }

            Marshal.FreeCoTaskMem(pReturnedString);

            foreach (string item in items)
            {
                string[] ary = item.Split('=');
                dictionary.Add(ary[0], ary[1]);

            }

            return dictionary;
        }

        public string ReadIniKeys(string section, string keys, string filePath)
        {
            return ReadString(section, keys, "", filePath);
        }

        public static void DeleteKey(string section, string key ,string filePath)
        {
             WritePrivateProfileString(section, key, null, filePath);
            
        }
        public void AddNewSection(string sectionPrefix, string typeValue, string time, int choose, double[] position, string filePath)
        {
            int nextIndex = FindNextAvailableIndex(sectionPrefix, filePath);

            string newSectionName = $"{sectionPrefix}{nextIndex}";

            // 写入 Type 键值对
            INIWrite(newSectionName, "Type", typeValue, filePath);

            // 写入 Type 键值对
            INIWrite(newSectionName, "Time", time, filePath);

            // 写入 LayerType 键值对
            INIWrite(newSectionName, "Choose", choose.ToString(), filePath);

            // 写入 Position1, Position2, Position3 键值对
            WriteIntArrayToFile(newSectionName, "Position", position, filePath);
        }

        private int FindNextAvailableIndex(string sectionPrefix, string filePath)
        {
            int index = 0;
            while (true)
            {
                string sectionName = $"{sectionPrefix}{index}";
                if (string.IsNullOrEmpty(ReadIniKeys(sectionName, "Type", filePath)))
                    break;
                index++;
            }
            return index;
        }

        private void WriteIntArrayToFile(string section, string key, double[] array, string filePath)
        {
            StringBuilder arrayString = new StringBuilder();
            foreach (double item in array)
            {
                if (arrayString.Length > 0)
                    arrayString.Append(", ");
                arrayString.Append(item);
            }
            INIWrite(section, key, arrayString.ToString(), filePath);
        }

        public List<string> GetValuesFromSectionsStartingWith(string sectionPrefix, string filePath)
        {
            var values = new List<string>();
            var sections = new List<string>();

            // 获取所有节名称
            uint MAX_BUFFER = 32767;
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, filePath);

            if (bytesReturned > 0)
            {
                string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
                sections.AddRange(returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries));
            }

            Marshal.FreeCoTaskMem(pReturnedString);

            // 过滤出以指定前缀开头的节
            foreach (string section in sections)
            {
                if (section.StartsWith(sectionPrefix) && int.TryParse(section.Substring(sectionPrefix.Length), out _))
                {
                    values.Add(ReadIniKeys(section, "Type", filePath));
                }
            }

            return values;
        }

        public void DeleteSection(string sectionName, string filePath)
        {
            WritePrivateProfileString(sectionName, null, null, filePath);
        }

        public void ReorderAndRenameSections(string sectionPrefix, string filePath)
        {
            // 使用ANSI编码读取整个文件内容
            Encoding ansiEncoding = Encoding.GetEncoding("GB2312"); // 或者使用 Encoding.Default
            List<string> lines = File.ReadAllLines(filePath, ansiEncoding).ToList();
            var typeSections = new Dictionary<int, List<string>>(); // 存储 [Type] 节的内容
            var otherContent = new List<string>(); // 存储非 [Type] 节的内容
            int? currentSectionIndex = null; // 当前正在处理的 [Type] 节的索引

            // 解析文件内容,区分 [Type] 节和其他内容
            foreach (var line in lines)
            {
                if (line.Trim().StartsWith("[") && line.Trim().EndsWith("]")) // 匹配节标题
                {
                    string sectionName = line.Trim().Trim('[', ']');

                    if (sectionName.StartsWith(sectionPrefix) && int.TryParse(sectionName.Substring(sectionPrefix.Length), out int index))
                    {
                        // 如果是 [Type] 节,则记录其内容
                        currentSectionIndex = index;
                        if (!typeSections.ContainsKey(index))
                        {
                            typeSections[index] = new List<string>();
                        }
                        typeSections[currentSectionIndex.Value].Add(line); // 添加节标题本身
                    }
                    else
                    {
                        // 非 [Type] 节直接添加到otherContent
                        currentSectionIndex = null;
                        otherContent.Add(line);
                    }
                }
                else if (currentSectionIndex.HasValue)
                {
                    // 如果在 [Type] 节内,则添加到对应 [Type] 节的内容中
                    typeSections[currentSectionIndex.Value].Add(line);
                }
                else
                {
                    // 否则添加到otherContent
                    otherContent.Add(line);
                }
            }

            // 创建一个新的列表来存储更新后的内容
            List<string> updatedLines = new List<string>();

            // 添加其他内容
            updatedLines.AddRange(otherContent);

            // 对 [Type] 节进行排序并重命名,确保索引连续
            int newIndex = 0;
            foreach (var pair in typeSections.OrderBy(kvp => kvp.Key))
            {
                string oldSectionName = $"{sectionPrefix}{pair.Key}";
                string newSectionName = $"{sectionPrefix}{newIndex}";

                Console.WriteLine($"Replacing [{oldSectionName}] with [{newSectionName}]");

                // 更新节名,并将内容添加到updatedLines
                var sectionContent = pair.Value.Select(line =>
                    line.StartsWith("[") && line.EndsWith("]") ? $"[{newSectionName}]" : line
                ).ToList();

                updatedLines.AddRange(sectionContent);
                updatedLines.Add(""); // 空行分隔节
                newIndex++;
            }

            // 使用ANSI编码将更新后的内容写回到文件中
            File.WriteAllLines(filePath, updatedLines, ansiEncoding);

            // 提示用户操作完成
            Console.WriteLine("节已成功重命名!");
        }
    }
}
posted @ 2025-10-14 16:39  杰西卡若  阅读(9)  评论(0)    收藏  举报