用 VB 写一个类读写 INI 文件

PS:我的资源里面有一个完整的VB生成INI文件工程,虽然跟本文章并不配套,但是两者结合一下的效果还是很好的

点此下载工程

INI 文件是什么样子?——不会吧,这都不知道。INI 文件就是 Windows 中常见的以 .ini 为扩展名的文件,其内部格式和各部分的名称如下:



  [Section1]
  Key1=Value1
  Key2=Value2
  Key3=Vlaue3


  [Section2]
  Key1=Value1
  Key2=Value5
  Key4=Value4
  Key5=...




  ...


  INI 文件中分若干个段 (Section),每个段中有若干个键 (Key) 值 (Value) 对。一个键值对保存一个信息;段则将属性类似的一些键值对组织在一起。同一个段中不能出现两次以上同样的键,但不同的段中可以出现相同的键。


  现在明白了吗?要是还不明白,就到 Windows 里找两个 INI 文件看看,文本编辑器就可以打开的。明白了 INI 文件就要开始学习怎样在 VB 中读写 INI 了。


  VB 读写 INI 文件,难吗?不难,因为 Windows 已经为我们做好了一切,我们只需要调用它的 API 函数就可以了。为了读写 INI 文件,我们可能用到以下 API 函数:


    GetPrivateProfileInt
  GetPrivateProfileString
  WritePrivateProfileString


  其中 WritePrivateProfileString 是用来向 INI 文件写信息的,而 GetPrivateProfileInt 和 GetPrivateProfileString 则是用来从 INI 文件中读信息的,前者用于读取整型数据,后者则用于读取字符串型数据。


  上述三个 API 函数在 VB 中的申明和说明如下:


    Private Declare Function GetPrivateProfileInt Lib "kernel32" _
    Alias "GetPrivateProfileIntA" ( _ ' 返回所读取的长整型值
    ByVal lpApplicationName As String, _ ' 要读取的段 (Section) 名称
    ByVal lpKeyName As String, _ ' 要读取的的键 (Key) 名称
    ByVal nDefault As Long, _ ' 指定默认值,如果读取时出错,则返回该值
    ByVal lpFileName As String) As Long ' 指定要读的 INI 文件名


    Private Declare Function GetPrivateProfileString Lib "kernel32" _
    Alias "GetPrivateProfileStringA" ( _ ' 返回所读取的字符串值的真实长度
    ByVal lpApplicationName As String, _ ' 要读取的段 (Section) 名称
    ByVal lpKeyName As Any, _ ' 要读取的的键 (Key) 名称
    ByVal lpDefault As String, _ ' 指定默认值,如果读取时出错,则返回该值
    ByVal lpReturnedString As String, _ ' 指定接收返回值的字符串变量
    ByVal nSize As Long, _ ' 指定允许字符串值的最大长度
    ByVal lpFileName As String) As Long ' 指定要读的 INI 文件名


    Private Declare Function WritePrivateProfileString Lib "kernel32" _
    Alias "WritePrivateProfileStringA" ( _ ' 如果成功返回非 0 值,失败返回 0
    ByVal lpApplicationName As String, _ ' 要写入的段 (Section) 名称
    ByVal lpKeyName As Any, _ ' 要写入的的键 (Key) 名称
    ByVal lpString As Any, _ ' 要写入的值 (Value),以字符串表示
    ByVal lpFileName As String) As Long ' 指定要写的 INI 文件名




  我们的目的是要在 VB 中写一个读写 INI 文件的类,所以在 VB 中新建一个工程,并添加一个类模块 (Class Module),命令类为 CIniFile,并且将上面的申明添加到类模块中。然后开始为类添加属性和方法。


  从上面的注释中,我们可以知道,每次调三个 API 之一都需要指定 INI 文件名。而在我们的 CIniFile 的每一个实例中,应该始终访问同一个 INI 文件,所以属性之一就是文件名:


Private IniFileName As String


  另外,调用 API 的过程中可能会出现错误,那么 CIniFile 应该能提供错误信息,所以定义一个保存错误信息的变量作为 CIniFile 的第二个属性


Public ErrorMsg As String


  由于访问什么段、什么键以及写入什么值都可以通过参数的形式传递给方法,而获取的值也都可以通过方法的返回值得以,所以不再需要其它属性了。不过在定义方法之前还需要对属性进行初始化:


Private Sub Class_Initialize()
   IniFileName = vbNullString
   ErrorMsg = vbNullString
End Sub




  为了指定 INI 文件名给 CIniFile,需要定义一个方法:


Public Sub SpecifyIni(FilePathName)
 IniFileName = Trim(FilePathName)
End Sub




  在每次读写值之前还需要先判断是否已经指定了 INI 文件名,不然读什么写什么啊?


Private Function NoIniFile() As Boolean
   NoIniFile = True
   If IniFileName = vbNullString Then
      ErrorMsg = "没有指定 INI 文件"
      Exit Function
   End If
   ErrorMsg = vbNullString
   NoIniFile = False
End Function




  准备工作完成,现在才是重头戏,读写 INI 文件。似乎“写”要简单一些,就先“写”吧:


Public Function WriteString(Section As String, key As String, Value As String) As Boolean
    WriteString = False
    If NoIniFile() Then
        Exit Function
    End If
    If WritePrivateProfileString(Section, key, Value, IniFileName) = 0 Then
        ErrorMsg = "写入失败"
        Exit Function
    End If
    WriteString = True
End Function




  该方法在 INI 文件中写入一个键值,成功返回 True,失败返回 False。根据 WritePrivateProfileString 的需要,除了文件名这一参数不用提供之外,需要提供段名、键名和值三个参数,而且这三个参数当然来自用户。而 WritePrivateProfileString 是通过返回值是否为 0 来判断是否成功的,所以可以通过判断 WritePrivateProfileString 的返回值是否非 0 来返回 True 或 False。


  而读 INI 就要稍稍麻烦一点了,两个读取 INI 文件的的函数中,读取字符串那个虽然参数多些,但实现起来却更简单,所以,先写这个:


Public Function ReadString(Section As String, key As String, Size As Long) As String
    Dim ReturnStr As String
    Dim ReturnLng As Long
    ReadString = vbNullString
    If NoIniFile() Then
        Exit Function
    End If
    ReturnStr = Space(Size)
    ReturnLng = GetPrivateProfileString(Section, key, vbNullString, ReturnStr, Size, IniFileName)
    ReadString = Left(ReturnStr, ReturnLng)
End Function




  这个方法在 INI 文件中读取一个键值,作为字符串返回。如果参数 Size 给定的大小不够,将不能返回完整的值串,但不会有任何提示。


  写这个函数的关键在 ReturnStr 的初始化和取值上。VB 中是不需要对字符串进行初始化的,也不需要分配空间。但是这里如果不将它初始化为一个足够长的字符串,就不能正确返回结果。这和 C 语言的字符串有关,就不多说了。ReturnStr 的取值也需要有趣,要使用 Left() 函数将其截断。如果不截断,取得的结果字符串就会有 Size 那么长,除了取得的值以外,其余部分都是用空格填充的。其原因与前面一点相同,与 C 语言的字符串有关。当然 Left() 函数也可以使用 Trim() 代替,效果是一样的。


  最后我们不得不面对这个最麻烦的 ReadInt 方法了。它为什么麻烦呢?看看现在的函数定义就知道了:


Public Function ReadInt(Section As String, key As String) As Long
    Dim ReturnLng As Long
    ReadInt = 0
    ReturnLng = GetPrivateProfileInt(Section, key, 0, IniFileName)
    If ReturnLng = 0 Then
        ReturnLng = GetPrivateProfileInt(Section, key, 1, IniFileName)
        If ReturnLng = 1 Then
            ErrorMsg = "不能读取"
            Exit Function
        End If
    End If
    ReadInt = ReturnLng
End Function




  这个方法在 INI 文件中读取一个整数值,失败时返回 0。考虑到某些键的值也可能为 0,故应结合 ErrorMsg 判断是否成功。


  这个方法中调用了两次 GetPrivateProfileInt,为什么要这样呢?因为 GetPrivateProfileInt 如果成功则返回取得的值,如果不成功则返回给定的默认值。这样就会出现一种情况:如果我给的默认值是 0,GetPrivateProfileInt 函数取得的值也是 0,那么它是成功还是失败呢?同样,如果我给的默认值是 1,GetPrivateProfileInt 函数取得的值也是 1,那就是成功还是失败呢?既然一次取值无法判断,那就多取一次,第一次设定默认值为 0,第二次设定默认值为 1,INI 文件的中值不会跟着我的默认值变吧?!虽然这样麻烦一些,但毕竟把问题解决了。


自此,我们终于把一个 CIniFile 写完了——现在读写 INI 文件再也不需要像写 CIniFile 一样考虑许多东西了,CIniFile 已经帮我们做了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值