VB如何操作INI文件

来源:互联网 发布:mac预览全屏快捷键 编辑:程序博客网 时间:2024/05/18 12:32

在程序中经常要用到设置或者其他少量数据的存盘,以便程序在下一次执行的时候可以使用,比如说保存本次程序执行时窗口的位置、大小、一些用户设置的数据等等,在 Dos 下编程的时候,我们一般自己产生一个文件,由自己把这些数据写到文件中,然后在下一次执行的时候再读出来使用。在 Win32 编程中当然你也可以这样干,但 Windows 已经为我们提供了两种方便的办法,那就是使用注册表或者 ini 文件(Profile)来保存少量数据。本文中先介绍一下 .ini 文件的使用。

ini 文件是文本文件,中间的数据格式一般为:
[Section1 Name]
KeyName1=value1
KeyName2=value2
...

[Section2 Name]
KeyName1=value1
KeyName2=value2

ini 文件可以分为几个 Section,每个 Section 的名称用 [] 括起来,在一个 Section 中,可以有很多的 Key,每一个 Key 可以有一个值并占用一行,格式是 Key=value,Win32 对 ini 文件操作的 api 中,有一部分是对 win.ini 操作的,有一部分是对用户自定义的 ini 文件操作的。Win.in 和 system.ini 是Windows的两个非常重要的初始化文件,Windows将用户所作的选择以及各种变化的系统信息记录在这两个文件中。System.ini 描述了系统硬件的当前状态,Win.ini 文件则包含了Windows 系统运行环境的当前配置。由于 Win.ini 文件的重要性和常用性,Win32 中有专门对 Win.ini 进行操作的 api,它们是:

GetProfileInt - 从 Win.ini 文件的某个 Section 取得一个 key 的整数值,它的原形是:

GetProfileInt(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
INT nDefault // 如果 Key 值没有找到,则返回缺省的值是多少
);

如果 Key 值没有找到的话,返回值是 nDefault 指定的缺省值,如果 Key 中的值是负数,则返回 0,如果 Key 指定的是数字和字符串的混合,则返回数字部分的值,比如说 x=1234abcd,则返回 1234


GetProfileString - 从 Win.ini 文件的某个 Section 取得一个 key 的字符串,它的原形是:

GetProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
LPCTSTR lpDefault, // 如果 Key 值没有找到,则返回缺省的字符串的地址
LPTSTR lpReturnedString, // 返回字符串的缓冲区地址
DWORD nSize // 缓冲区的长度
);

返回的字符串在缓冲区内,返回的 eax 值是返回的字符串的长度(不包括尾部的0)


GetProfileSection - 从 Win.ini 文件中读出整个 Section 的内容,它的原形是:

GetProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPTSTR lpReturnedString, // 返回数据的缓冲区地址
DWORD nSize // 返回数据的缓冲区长度
);


WriteProfileSection - 将一个整个 Section 的值 写入 Win.ini 文件的指定 Section 中,它的原形是:

WriteProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpString // 要写入的数据的地址
);

如果 Win.ini 没有指定的 Section,API 会新建立一个并写入数据,如果已经存在,则先删除原来 Seciton 中所有的 Key 值然后写入新的。


WriteProfileString - 将一个 Key 值写入 Win.ini 文件的指定 Section 中,它的原形是:

WriteProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
LPCTSTR lpString // 要写的字符串地址
);

如果 Win.ini 没有指定的 Section,API 会新建 Section,如果没有指定的 Key 则新建一个 Key 并写入数据,如果已经存在,则用字符串代替原来的值。
以上的 Api 是对 Win.ini 操作的,当然对于我们来说,用的更多的是在程序运行的目录中建立自己的 ini 文件,如果需要对自己的 ini 文件操作,就要用到另一组 Api,这一组 api 和上面的很象,只要把上面一组的 Profile 换成 PrivateProfile(私有的)就可以了,参数中也相应的多了一个 ini 文件名的参数。例如 GetPrivateProfileInt、GetPrivateProfileSection、WritePrivateProfileString 等等, 下面分别介绍:

GetPrivateProfileInt - 从 ini 文件的某个 Section 取得一个 key 的整数值,它的原形是:

GetPrivateProfileInt(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
INT nDefault // 如果 Key 值没有找到,则返回缺省的值是多少
LPCTSTR lpFileName // ini 文件的文件名
);

中间参数和返回值的定义和 GetProfileInt 是一样的。


GetPrivateProfileString - 从 ini 文件的某个 Section 取得一个 key 的字符串,它的原形是:

GetPrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
LPCTSTR lpDefault, // 如果 Key 值没有找到,则返回缺省的字符串的地址
LPTSTR lpReturnedString, // 返回字符串的缓冲区地址
DWORD nSize // 缓冲区的长度
LPCTSTR lpFileName // ini 文件的文件名
);


GetPrivateProfileSection - 从 ini 文件中读出整个 Section 的内容,它的原形是:

GetPrivateProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPTSTR lpReturnedString, // 返回数据的缓冲区地址
DWORD nSize // 返回数据的缓冲区长度
LPCTSTR lpFileName // ini 文件的文件名
);

这个 api 可以读出整个 section 的内容,当你不知道 section 中有哪些 key 的时候,可以使用这个 api 将整个 section 读出后再处理。


GetPrivateProfileSectionNames - 从 ini 文件中获得 Section 的名称,它的原形是:

GetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, // 返回数据的缓冲区地址
DWORD nSize // 返回数据的缓冲区长度
LPCTSTR lpFileName // ini 文件的文件名
);

如果 ini 中有两个 Section: [sec1] 和 [sec2],则返回的是 'sec1',0,'sec2',0,0 ,当你不知道 ini 中有哪些 section 的时候可以用这个 api 来获取名称


WritePrivateProfileSection - 将一个整个 Section 的内容入 ini 文件的指定 Section 中,它的原形是:

WritePrivateProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpString // 要写入的数据的地址
LPCTSTR lpFileName // ini 文件的文件名
);


WritePrivateProfileString - 将一个 Key 值写入 ini 文件的指定 Section 中,它的原形是:

WritePrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名称的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名称的字符串地址
LPCTSTR lpString // 要写的字符串地址
LPCTSTR lpFileName // ini 文件的文件名
);

如果 ini 中没有指定的 Section,API 会新建 Section,如果没有指定的 Key 则新建一个 Key 并写入数据,如果已经存在,则用字符串代替原来的值。当指定的 ini 也不存在的时候,API 会自动建立一个新的文件,所以使用 ini 的好处是我们不必为了保存少量的数据涉及到文件操作,就连查找文件是否存在的操作都不必要。

使用要点:

在我们实际使用的时候,用的最多的是 GetPrivateProfileString 和 WritePrivateProfileString,但在对自定义 ini 文件操作的时候要注意的是,如果 lpFileName 指定的文件没有路径的话,Api 会去 Windows 的安装目录去找而不会在当前目录找,但是每次用到 ini 函数要获取当前路径显然太麻烦了,这里有一个变通的办法,你只要在 ini 文件名前面加上 ./ 就可以了,比如说要对本目录下的 user.ini 操作,那么文件名就是 './user.ini' 这样显然比较方便。另外,当你要把一个 Key 清除的时候,可以使用把 lpString 指向一个空的字符串然后使用 WritePrivateProfileString。当你要把一个 section 的全部内容清空的时候,也不必把 key 一个个的清除,可以使用把 lpString 指向一个空的字符串然后使用 WritePrivateProfileSection。

 

 

 

 

可以使用两个API实现配置文件的读写
读:GetPrivateProfileString
写:WritePrivateProfileString
 
-----------------------------------------------------------
1. 
WritePrivateProfileString'ini 

VB
声明 
Declare Function WritePrivateProfileString& Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As String, ByVal lpFileName As String) 

说明 
在初始化文件指定小节内设置一个字串 

返回值 
Long
,非零表示成功,零表示失败。会设置GetLastError 

参数表 
lpApplicationName String
,要在其中写入新字串的小节名称。这个字串不区分大小写 
lpKeyName Any
,要设置的项名或条目名。这个字串不区分大小写。用vbNullString可删除这个小节的所有设置项 
lpString String
,指定为这个项写入的字串值。用vbNullString表示删除这个项现有的字串 
lpFileName String
,初始化文件的名字。如果没有指定完整路径名,则windows会在windows目录查找文件。如果文件没有找到,则函数会创建它 

其他 
vbapi文本查看器里复制的声明如下:
Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long 

-----------------------------------------------------------
2. GetPrivateProfileString '
ini

VB
声明 
Declare Function GetPrivateProfileString& Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) 

说明 
为初始化文件中指定的条目取得字串 

返回值 
Long
,复制到lpReturnedString缓冲区的字节数量,其中不包括那些NULL中止字符。如lpReturnedString缓冲区不够大,不能容下全部信息,就返回nSize-1(若lpApplicationNamelpKeyNameNULL,则返回nSize-2 

参数表 
lpApplicationName String
,欲在其中查找条目的小节名称。这个字串不区分大小写。如设为vbNullString,就在lpReturnedString缓冲区内装载这个ini文件所有小节的列表 
lpKeyName String
,欲获取的项名或条目名。这个字串不区分大小写。如设为vbNullString,就在lpReturnedString缓冲区内装载指定小节所有项的列表 
lpDefault String
,指定的条目没有找到时返回的默认值。可设为空("" 
lpReturnedString String
,指定一个字串缓冲区,长度至少为nSize 
nSize Long
,指定装载到lpReturnedString缓冲区的最大字符数量 
lpFileName String
,初始化文件的名字。如没有指定一个完整路径名,windows就在Windows目录中查找文件 

注解 
lpKeyName参数为vbNullString,那么lpReturnedString缓冲区会载入指定小节所有设置项的一个列表。每个项都用一个NULL字符分隔,最后一个项用两个NULL字符中止。也请参考GetPrivateProfileInt函数的注解

其他 
vbapi文本查看器中复制的声明为:Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long 

===================================================================
举例如下:
Option Explicit

Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

Private Sub Form_Load()

    '
写配置文件
    WritePrivateProfileString "OK", "isOK", "True", "c:/vb-test.ini"
    WritePrivateProfileString "sushe", "mail", "xmsailor@sohu.com", "c:/vb-test.ini"
    
    ' 
读配置文件如下
    Dim myweb As String
    myweb = String(255, 0)
    GetPrivateProfileString "sushe", "web", "
没有配置web", myweb, 255, "c:/vb-test.ini"
    MsgBox myweb, vbOKOnly, "web"

End Sub


----------------
c:/vb-test.ini
文件的内容如下

[sushe]
name=xmsailor
comp=cvicse
mail=xmsailor@sohu.com
web=friends.sdu.edu.cn
year=1999

[OK]
isOK=True
isSucceed=True
 
 
 
 
 
 
为了方便用户使用和使系统具有灵活性,大多数Win-dows应用程序将用户所做的选择以及各种变化的系统信息记录在初始化(INI)文件中。因此,当系统的环境发生变化时,可以直接修改INI文件,而无需修改程序。由此可见,INI文件对系统功能是至关重要的。本文将介绍采用VisualBasicforWindows(下称VB)开发Windows应用程序时如何读写INI文件。

INI
文件是文本文件,由若干部分(section)组成,在每个带括号的标题下面,是若干个以单个单词开头的关键词(keyword)和一个等号,每个关键词会控制应用程序某个功能的工作方式,等号右边的值(value)指定关键词的操作方式。其一般形式如下:

[section1]
keyword1=valuel
keyword2=value2
……
[section2]
keyword1=value1
keyword2=value2
……

其中,如果等号右边无任何内容(value为空),那就表示Windows应用程序已为该关键词指定了缺省值,如果在整个文件中找不到某个关键词(或整个一部分),那同样表示为它们指定了缺省值。各个部分所出现的顺序是无关紧要的,在每一个部分里,各个关键词的顺序同样也无关紧要。

读写INI文件通常有两种方式:一是在Windows中用"记事本"(Notepad)对其进行编辑,比较简单,无需赘述;二是由Windows应用程序读写INI文件,通常是应用程序运行时读取INI文件中的信息,退出应用程序时保存用户对运行环境的某些修改。

关键词的值的类型多为字符串或整数型,应分两种情况读写。为了使程序具有可维护性和可移植性,最好把对INI文件的读写封装在一个模块(RWINI.BAS)中,在RWI-NI.BAS中构造GetIniSGetIniN函数以及SetIniSSe-tIniN过程,在这些函数和过程中需要使用WindowsAPI"GetPrivateprofileString""GetPrivateProfileInt""WritePrivateProfileString"函数。

RWINI.BAS
模块的程序代码如下:

General-Declearation部分中声明使用到的WindowsAPI函数:

Declare Function GetprivateprofileString Lib"Ker-nel"(ByVallpAppName As String
ByVallpKeyName As StringByVallpDefault As StringByVal lpRetrm-String As StringByVal cbReturnString As IntegerByVal Filename As String)As Integer
Declare FunctionGetPrivatePfileInt Lib "Kernel"(ByVal lpAppName As String
ByVal lpKeyName As StringByVal lpDefault As IntegerByVal Filename As String)As Integer
Declare FuncitonWritePrivateprofileString Lib "Kernel"(ByVal lpApplicationName As String
ByVal lpKeyName As StringByVal lpString As StringByVal lplFileName As String)As Integer
Function GetIniS(ByVal SectionName As String
ByVal KeyWord As StringByVal DefString As String)As String
Dim ResultString As String * 144
Temp As Integer
Dims As String
i As Integer
Temp%=GetPrivateProfileString(SectionName
KeyWord""ResultString144AppProfileName())
检索关键词的值
IfTemp%
0Then‘关键词的值不为空
s=""
Fori=1To144
IfAsc(Mid$(ResultString
I1))=0Then
ExitFor
Else
s=s&Mid$(ResultString
I1)
EndIf
Next
Else
Temp%=WritePrivateProfilesString(sectionname
KeyWordDefStringppProfileName())
将缺省值写入INI文件
s=DefString
EndIf
GetIniS=s
EndFunction
FunctionGetIniN(ByValSectionNameAsString
ByValKeyWordAsStringByValDefValue
AsIneger)AsInteger
DimdAsLong
sAsString
d=DefValue
GetIniN=GetPrivateProfileInt(SectionName

KeyWord
DefValueppProfileName())
Ifd
<>DefValueThen
s=""&d
d=WritePrivateProfileString(SectionName

KeyWord
sAppProfileName())
EndIf
EndFunction
SubSetIniS(ByValSectionNameAsString
BtVaKeyWordAsStringByValValStr
AsString)
Dimres%
res%=WritePrivateprofileString(SectionName
KeyWordValStrAppProfileName())
EndSub
SubSetIniN(ByValSectionNameAsString
ByValKeyWordAsStringByValValInt
AsInteger)
Dimres%
s$
s$=Str$(ValInt)
res%=WriteprivateProfileString(SectionName
KeyWords$AppProfileName())
EndSub

SectionName
为每一部分的标题,KeyWord为关键词,GetIniSGetIniN中的DefValue为关键词的缺省值,SetIniSSetIniNValStrValInt为要写入INI文件的关键词的值。为了能更好地说明如何使用以上函数和过程,下面举两个实例。

实例1:

开发应用程序通常要使用数据库和其它一些文件,这些文件的目录(包括路径和文件名)不应在程序中固定,而是保存在INI文件中,程序运行时由INI文件中读入。读入数据库文件的代码如下:
DimDatabasenameAsString
Databasename=GetIniS("
数据库""职工""")
IfDatabaseName=""ThenDatabaseName=InputBox("
请输入数据库《职工》的目录")
App.Title)’
也可通过"文件对话框"进行选择
OnErrorResumeNext
Setdb=OpenDatabas(DatabaseName)
IfErr
<>0Then
MsgBox"
打开数据库失败!"MB-
ICONSTOP
App.Title:GotoErrorProcessing
Else
SetIniS"
数据库""职工"DatabaseName
EndIf
OnErrorGoTo0
……
实例2:

为了方便用户操作,有时需要保存用户界面的某些信息,例如窗口的高度和宽度等。装载窗体时,从INI文件中读入窗体高度和宽度,卸载窗体时将窗体当前高度和宽度存入INI文件,代码如下:
Sub Form1_Load()
……
Forml.Height=GetIniN("
窗体1""高度"6000)
Form1.Width=GetIniN("
窗体1""高度"4500)
EndSub
……
Sub Form1_Unload()
……
SetIniN"
窗体1""高度"Me.Height
SetIniN"
窗体1"宽度"Me.Width
……
End Sub