winform中C#操作ini

网载的,进行了一些修改,测试可行。

方法一:

网上的一个ini操作类

public class IniClass
    {
        public string inipath;
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, 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);

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="IniPath">文件路径</param>
        public IniClass(string IniPath)
        {
            inipath = IniPath;
        }


        /// <summary>
        /// 写入Ini文件
        /// </summary>
        /// <param name="Section">项目名称(如 [TypeName] )</param>
        /// <param name="Key">键</param>
        /// <param name="Value">值</param>
        /// <returns>复制到lpReturnedString缓冲区的字节数量,其中不包括那些NULL中止字符。</returns>
        public long IniWriteValue(string Section, string Key, string Value)
        {
            return WritePrivateProfileString(Section, Key, Value, this.inipath);
        }

        /// <summary>
        /// 读出INI文件
        /// </summary>
        /// <param name="Section">项目名称(如 [TypeName] )</param>
        /// <param name="Key">键</param>
        public string IniReadValue(string Section, string Key)
        {
            StringBuilder temp = new StringBuilder(500);
            int i = GetPrivateProfileString(Section, Key, "", temp, 500, this.inipath);
            return temp.ToString();
        }

        /// <summary>
        /// 验证文件是否存在
        /// </summary>
        /// <returns>布尔值</returns>
        public bool ExistIniFile()
        {
            return File.Exists(inipath);
        }
    }

调用:

        private void button1_Click(object sender, EventArgs e)
        {
            IniClass ini = new IniClass(@"D:\ce\ini\bin\Debug\list.ini");//此处一定要是绝对路径,否则可能读不出值。
            MessageBox.Show(ini.IniReadValue("root", "1n"));
            ini = null;
        }


ini文件内容

[root]
1n=11111111111111111111
1u=222222222222222

------------------------------------------------------------------------------------------------------------------------------------------------------------

方法二:

也是一个ini读写类,比上面的那个全

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections;
using System.Collections.Specialized;

namespace wuyisky{
  /**//**/
  /** <summary>
  /// IniFiles的类
  /// </summary>
  public class IniFiles
  {
    public string FileName; //INI文件名
    //声明读写INI文件的API函数
    [DllImport("kernel32")]
    private static extern bool WritePrivateProfileString(string section, string key, string val, string filePath);
    [DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath);
    //类的构造函数,传递INI文件名
    public IniFiles(string AFileName)
    {
      // 判断文件是否存在
      FileInfo fileInfo = new FileInfo(AFileName);
      //Todo:搞清枚举的用法
      if ((!fileInfo.Exists))
      { //|| (FileAttributes.Directory in fileInfo.Attributes))
        //文件不存在,建立文件
        System.IO.StreamWriter sw = new System.IO.StreamWriter(AFileName, false, System.Text.Encoding.Default);
        try
        {
          sw.Write("#表格配置档案");
          sw.Close();
        }

        catch
        {
          throw (new ApplicationException("Ini文件不存在"));
        }
      }
      //必须是完全路径,不能是相对路径
      FileName = fileInfo.FullName;
    }
    //写INI文件
    public void WriteString(string Section, string Ident, string Value)
    {
      if (!WritePrivateProfileString(Section, Ident, Value, FileName))
      {
 
        throw (new ApplicationException("写Ini文件出错"));
      }
    }
    //读取INI文件指定
    public string ReadString(string Section, string Ident, string Default)
    {
      Byte[] Buffer = new Byte[65535];
      int bufLen = GetPrivateProfileString(Section, Ident, Default, Buffer, Buffer.GetUpperBound(0), FileName);
      //必须设定0(系统默认的代码页)的编码方式,否则无法支持中文
      string s = Encoding.GetEncoding(0).GetString(Buffer);
      s = s.Substring(0, bufLen);
      return s.Trim();
    }

    //读整数
    public int ReadInteger(string Section, string Ident, int Default)
    {
      string intStr = ReadString(Section, Ident, Convert.ToString(Default));
      try
      {
        return Convert.ToInt32(intStr);

      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        return Default;
      }
    }

    //写整数
    public void WriteInteger(string Section, string Ident, int Value)
    {
      WriteString(Section, Ident, Value.ToString());
    }

    //读布尔
    public bool ReadBool(string Section, string Ident, bool Default)
    {
      try
      {
        return Convert.ToBoolean(ReadString(Section, Ident, Convert.ToString(Default)));
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        return Default;
      }
    }

    //写Bool
    public void WriteBool(string Section, string Ident, bool Value)
    {
      WriteString(Section, Ident, Convert.ToString(Value));
    }

    //从Ini文件中,将指定的Section名称中的所有Ident添加到列表中
    public void ReadSection(string Section, StringCollection Idents)
    {
      Byte[] Buffer = new Byte[16384];
      //Idents.Clear();

      int bufLen = GetPrivateProfileString(Section, null, null, Buffer, Buffer.GetUpperBound(0),
       FileName);
      //对Section进行解析
      GetStringsFromBuffer(Buffer, bufLen, Idents);
    }

    private void GetStringsFromBuffer(Byte[] Buffer, int bufLen, StringCollection Strings)
    {
      Strings.Clear();
      if (bufLen != 0)
      {
        int start = 0;
        for (int i = 0; i < bufLen; i++)
        {
          if ((Buffer[i] == 0) && ((i - start) > 0))
          {
            String s = Encoding.GetEncoding(0).GetString(Buffer, start, i - start);
            Strings.Add(s);
            start = i + 1;
          }
        }
      }
    }
    //从Ini文件中,读取所有的Sections的名称
    public void ReadSections(StringCollection SectionList)
    {
      //Note:必须得用Bytes来实现,StringBuilder只能取到第一个Section
      byte[] Buffer = new byte[65535];
      int bufLen = 0;
      bufLen = GetPrivateProfileString(null, null, null, Buffer,
       Buffer.GetUpperBound(0), FileName);
      GetStringsFromBuffer(Buffer, bufLen, SectionList);
    }
    //读取指定的Section的所有Value到列表中
    public void ReadSectionValues(string Section, NameValueCollection Values)
    {
      StringCollection KeyList = new StringCollection();
      ReadSection(Section, KeyList);
      Values.Clear();
      foreach (string key in KeyList)
      {
        Values.Add(key, ReadString(Section, key, ""));
  
      }
    }
    /**/读取指定的Section的所有Value到列表中,
    //public void ReadSectionValues(string Section, NameValueCollection Values,char splitString)
    //{  string sectionValue;
    //  string[] sectionValueSplit;
    //  StringCollection KeyList = new StringCollection();
    //  ReadSection(Section, KeyList);
    //  Values.Clear();
    //  foreach (string key in KeyList)
    //  {
    //    sectionValue=ReadString(Section, key, "");
    //    sectionValueSplit=sectionValue.Split(splitString);
    //    Values.Add(key, sectionValueSplit[0].ToString(),sectionValueSplit[1].ToString());
 
    //  }
    //}
    //清除某个Section
    public void EraseSection(string Section)
    {
      //
      if (!WritePrivateProfileString(Section, null, null, FileName))
      {

        throw (new ApplicationException("无法清除Ini文件中的Section"));
      }
    }
    //删除某个Section下的键
    public void DeleteKey(string Section, string Ident)
    {
      WritePrivateProfileString(Section, Ident, null, FileName);
    }
    //Note:对于Win9X,来说需要实现UpdateFile方法将缓冲中的数据写入文件
    //在Win NT, 2000和XP上,都是直接写文件,没有缓冲,所以,无须实现UpdateFile
    //执行完对Ini文件的修改之后,应该调用本方法更新缓冲区。
    public void UpdateFile()
    {
      WritePrivateProfileString(null, null, null, FileName);
    }

    //检查某个Section下的某个键值是否存在
    public bool ValueExists(string Section, string Ident)
    {
      //
      StringCollection Idents = new StringCollection();
      ReadSection(Section, Idents);
      return Idents.IndexOf(Ident) > -1;
    }

    //确保资源的释放
    ~IniFiles()
    {
      UpdateFile();
    }
  }
}

INI文件是文本文件,由若干节(section)组成,在每个带括号的标题下面,是若干个关键词(key)及其对应的值(Value)

  [Section]

  Key=Value


-----------------------------------------------------------------------------------------------------------------------------------------------------------


1、C#操作INI的方法一般是采用调用DLL中的INI文件的函数

#region 导入DLL函数
[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileString(string segName, string keyName, string sDefault, StringBuilder buffer, int nSize, string fileName);

public extern static int GetPrivateProfileStringA(string segName, string keyName, string sDefault, byte[] buffer, int iLen, string fileName); // ANSI版本

[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileSection(string segName, StringBuilder buffer, int nSize, string fileName);

[DllImport("kernel32.dll")]
public extern static int WritePrivateProfileSection(string segName, string sValue, string fileName);

[DllImport("kernel32.dll")]
public extern static int WritePrivateProfileString(string segName, string keyName, string sValue, string fileName);

[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileSectionNamesA(byte[] buffer, int iLen, string fileName);

#endregion

2、 INI文件的fileName必须使用绝对路径,说明如下

If the lpFileName parameter does not contain a full path and file name for the file,
WritePrivateProfileString searches the Windows directory for the file. 
If the file does not exist,this function creates the file in the Windows directory.

3、封装的方法中,最有价值的是获取所有Sections和所有的Keys,网上关于这个的代码大部分是错误的,这里给出一个正确的方法:

/// 返回该配置文件中所有Section名称的集合

public ArrayList ReadSections() {
byte[] buffer = new byte[65535];
int rel = GetPrivateProfileSectionNamesA(buffer, buffer.GetUpperBound(0), _FileName);
int iCnt, iPos;
ArrayList arrayList = new ArrayList();
string tmp;
if (rel>0) {
iCnt = 0; iPos = 0; 
for (iCnt = 0; iCnt < rel; iCnt++) {
if (buffer[iCnt] == 0x00) {
tmp =System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt-iPos ).Trim();
iPos = iCnt + 1;
if (tmp != "")
arrayList.Add(tmp);
}
}
}
return arrayList;
}

// 获取节点的所有KEY值

public ArrayList ReadKeys(string sectionName) {

byte[] buffer = new byte[5120];
int rel = GetPrivateProfileStringA(sectionName, null, "", buffer, buffer.GetUpperBound(0), _FileName);

int iCnt, iPos;
ArrayList arrayList = new ArrayList();
string tmp;
if (rel > 0) {
iCnt = 0; iPos = 0;
for (iCnt = 0; iCnt < rel; iCnt++) {
if (buffer[iCnt] == 0x00) {
tmp = System.Text.ASCIIEncoding.Default.GetString(buffer, iPos, iCnt-iPos).Trim();
iPos = iCnt + 1;
if (tmp != "")
arrayList.Add(tmp);
}
}
}
return arrayList;
}

 

4、得到某个节点下面所有的key和value组合

/// <summary>
/// 得到某个节点下面所有的key和value组合
/// </summary>
/// <param name="section"></param>
/// <param name="keys"></param>
/// <param name="values"></param>
/// <param name="path"></param>
/// <returns></returns>
public static int GetAllKeyValues(string section, out string[] keys, out string[] values, string path)
{
      byte[] b = new byte[65535];

      GetPrivateProfileSection(section, b, b.Length, path);
      string s = System.Text.Encoding.Default.GetString(b);
      string[] tmp = s.Split((char)0);
      ArrayList result = new ArrayList();
      foreach (string r in tmp)
      {
           if (r != string.Empty)
               result.Add(r);
      }
      keys = new string[result.Count];
      values = new string[result.Count];
      for (int i = 0; i < result.Count; i++)
      {
           string[] item = result[i].ToString().Split(new char[] { '=' });
           if (item.Length == 2)
           {
               keys[i] = item[0].Trim();
               values[i] = item[1].Trim();
           }
           else if (item.Length == 1)
           {
               keys[i] = item[0].Trim();
               values[i] = "";
           }
           else if (item.Length == 0)
           {
               keys[i] = "";
               values[i] = "";
           }
       }
       return 0;
}

5、批判网上一个常见的代码范例

public string ReadString(string Section, string Key) {
StringBuilder buffer= new StringBuilder(65535); 
GetPrivateProfileString(Section, Key, "", buffer, buffer.Capacity, _FileName); 
return buffer.ToString(); 
}

用StringBuilder只能读出第一行,不是一个好的写法,正确的做法应该是用char[],因为返回的是一个二进制的串,字符串之间是用"\0"分隔的,具体的见我前面的代码。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值