//****************************
第二部分: INI 文件
INI 文件的讀寫(xiě)
Windows 操作系統將 win.ini 作為記錄當前系統狀態(tài),并根據其記錄內容對系統進(jìn)行配置的一種便捷的方法,且眾多的應用軟件也廣泛的使用該類(lèi)型的配置文件來(lái)對軟件進(jìn)行記錄和配置。
配置設置文件( INI )文件是 windows 操作系統中的一種特殊的 ASCII 文件,以 ini 為文件擴展名。該文件也被稱(chēng)為初始化文件 initialization file 和概要文件 profile ,通常應用程序可以擁有自己的配置設置文件來(lái)存儲狀態(tài)信息。一般來(lái)說(shuō)私有的配置設置文件比較小,這樣可以減少程序在初始化時(shí)讀取配置文件時(shí)的信息量,從而提高程序的啟動(dòng)速度、提高應用程序和系統的性能。
如果帶存取的信息涉及到 windows 系統環(huán)境或是其他應用程序時(shí),就必須在 windows 系統的配置文件 win.ini 中記錄并在訪(fǎng)問(wèn)的同時(shí)發(fā)送 WM_WININICHANGE 消息給所有的頂層窗口,通知其他的程序系統配置文件已做了更改。但由于 win.ini 中不僅記錄了系統的有關(guān)信息,也存儲著(zhù)許多其他應用軟件的配置數據,所以訪(fǎng)問(wèn)的數據量要遠比私有配置文件大的多。
掌握內容 :
了解 INI 文件的結構;能夠正確靈活的應用 INI 文件存取信息;避免 INI 文件讀寫(xiě)的常見(jiàn)誤區。
INI 文件存儲管理
配置文件里的信息之所以能為系統和終生的軟件所讀取并識別,是由于其內部對數據的存取采用了預先約定的“項 - 值對( entry-value pairs )”存儲結構,并對待存取的數據分門(mén)別類(lèi)地進(jìn)行調理清晰的存儲。 INI 文件的結構如下:
;注釋
[ 小節名 ]
關(guān)鍵字 = 值
…
INI 文件允許有多個(gè)小節,每個(gè)小節又允許有多個(gè)關(guān)鍵字,“ = ”后面是該關(guān)鍵字的值。值的類(lèi)型有 3 種:字符串、整型數值和布爾值。其中字符串存儲在 INI 文件中時(shí)沒(méi)有引號,布爾值用 1 表示,布爾假值用 0 表示。
注釋以分號“;”開(kāi)頭。
Windows 操作系統專(zhuān)門(mén)為此提供了 6 個(gè) API 函數來(lái)對配置設置文件進(jìn)行讀、寫(xiě):
GetPrivateProfileInt: 從私有初始化文件(即自定義的 INI 文件)獲取整型數值。
GetPrivateProfileString: 從私有初始化文件獲取字符串型值。
GetProfileInt :從 win.ini 獲取整數值。
WritPrivateProfileString :寫(xiě)字符串到私有初始化文件。
WriteProfileString :寫(xiě)字符串到 win.ini 。
需要指出的是,當向配置文件存儲信息時(shí),不論是數據還是字符串都要先轉換成字符串,然后再進(jìn)行存儲。
這里只介紹私有初始化文件,所以只涉及到 3 個(gè)函數 ---GetPrivateProfileString 、 GetPrivateProfileInt 和 WritePrivateProfileString 。
INI 文件讀寫(xiě)過(guò)程
INI 文件的讀和寫(xiě)操作是分開(kāi)的,首先介紹寫(xiě)文件的方法。
1. INI 文件的寫(xiě)過(guò)程
將信息寫(xiě)入 INI 文件中所用的函數為:
BOOL WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpString,LPCTSTR lpFileName);
其中各參數的意義:
lpAppName :是 INI 文件中的一個(gè)字段名。
lpKeyName :是 lpAppName 下的一個(gè)鍵名,通俗講就是變量名。
lpString :是鍵值,也就是變量的值,不過(guò)必須為 LPCTSTR 型或 CString 型的。
lpFileName :是完整的 INI 文件名。
實(shí)例 1 :將信息寫(xiě)入 INI 文件
將一名學(xué)生的姓名和年齡寫(xiě)入 C:\student.ini 文件中。
步驟:創(chuàng )建基于對話(huà)框的 MFC 程序,刪除所有自動(dòng)生成的控件,然后添加按鈕控件,并在相應的按鈕事件處添加如下代碼:
CString strName,strTemp;
int nAge;
strName=" 張三 ";
nAge=12;
::WritePrivateProfileString("Info","Name",strName,"C:\\student.ini");
strTemp.Format("%d",nAge);
::WritePrivateProfileString("Info","Age",strTemp,"C:\\student.ini");
運行結果: C 盤(pán)下創(chuàng )建了 student.ini 文件,文件內容如下:
[Info]
Name= 張三
Age=12
2. INI 文件的讀過(guò)程
將信息從 INI 文件中讀出到程序中所用的函數為 :
DWORD GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefault,LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);
其中,各參數的意義如下:
前兩個(gè)參數與 WritePrivateProfileString 中的意義一樣。
lpDefault :如果 INI 文件中沒(méi)有前兩個(gè)參數指定的字段名或鍵名,則將此值賦給變量。
lpReturnedString :接收 INI 文件中沒(méi)有前兩個(gè)參數指定的字段名或鍵名,則將此值賦給變量。
lpReturnedString :接受 INI 文件中的值的 CString 對象,即目的緩存器。
nSize :目的緩存器的大小。
lpFileName :是完整的 INI 文件名。
實(shí)例 2 :從 INI 文件讀出信息
程序將 C:\student.ini 文件中的信息讀出到程序中。
步驟:如前,在相應的 button 按鈕響應事件函數處,添加如下代碼:
CString strStudName;
int nStudAge;
GetPrivateProfileString("Info","Name"," 默認姓名 ",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"C:\\student.ini");
// 讀入整型值
//UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);
nStudAge=GetPrivateProfileInt("Info","Age",10,"C:\\student.ini");
運行結果:可以通過(guò)設置斷點(diǎn),來(lái)查看 strStudName 和 nStudAge 的內容。
錯誤的 INI 文件讀寫(xiě)
1. 路徑指示錯誤
INI 文件的路徑必須完整,文件名前面的各級目錄必須存在,否則寫(xiě)入不成功,該函數返回 FALSE 值。
如下程序:
CString strName,strTemp;
int nAge;
strName=” 張三 ”;
nAge=12;
::WritePrivateProfileString(“Info”,”Name”,strName,”c:\\Info\student.ini”);
如果 C:\Info 目錄不存在,那么寫(xiě) INI 文件的操作就會(huì )失敗。
解決辦法是進(jìn)行文件操作前通過(guò)以下代碼檢查目錄是否存在:
WIN32_FIND_DATA fd;
HANDLE hFind=FindFirstFile(“C:\\Info”,&fd);
If((hFind!=INVALID_HANDLE_VALUE)&&(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
{
AfxMessageBox(“ 存在 ”) ;
}
else
{
AfxMessageBox(“ 不存在 ”) ;
}
FindClose(hFind);
2. 認識上的兩個(gè)誤區
誤區一:寫(xiě)文件路徑的時(shí)候寫(xiě)成諸如 C:\Info 的形式,實(shí)際上在 visual C++ 中,文件名的路徑中必須為 \\ ,因為在 visual C++ 中 \\ 才表示一個(gè) \ ,所以正確的格式應改為 C:\\Info.
誤區二:因為經(jīng)常需要把 INI 文件放在程序所在目錄,所以在寫(xiě) INI 文件的函數中直接將 lpFileName 參數設置為文件名,如“ student.ini ”。這是不正確的做法,打開(kāi) INI 文件的時(shí)候,如果文件名沒(méi)有指明路徑的話(huà),那么這個(gè) INI 文件會(huì )存儲在 windows 目錄中,而不是在應用程序的當前目錄中。
解決辦法是 lpFileName 參數設置為“ .\\student.ini ”。
教你一招 ---- 如何循環(huán)讀寫(xiě)多個(gè)值
假設現在有一個(gè)程序,要將最近使用的幾個(gè)文件名保存下來(lái),寫(xiě)入的代碼如下:
CString strTemp,strTempA;
int I;
int nCount=6;
for(i=0;i<nCount;i++)
{
strTemp.Format(“%d”,i);
strTemp.Format(“%s%d%s”,”File”,i,”.txt”);// 文件名
::WritePrivateProfileStirng(“UseFileName”,”FileName”+strTemp,strTempA,”c:\\usefile.ini”);
}
strTemp.Format(“%d”,nCount);
::WritePrivateProfileString(“FileCount”,”Count”,strTemp,”C:\\usefile.ini”);
// 將文件總數寫(xiě)入,以便讀出。
以上代碼運行后, C 盤(pán)下面 userfile.ini 文件內容。
實(shí)例 3 :將信息寫(xiě)入 INI 文件
步驟:創(chuàng )建基于對話(huà)框的 MFC 程序,刪除所有自動(dòng)生成的控件,然后添加按鈕控件,并在相應的按鈕事件處添加如下代碼:
CString strTemp,strTempA;
int i;
int nCount=6;
for(i=0;i<nCount;i++)
{
strTemp.Format("%d",i);
strTempA.Format("%s%d%s","File",i,".txt"); // 文件名
::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,"c:\\usefile.ini");
}
strTemp.Format("%d",nCount);
::WritePrivateProfileString("FileCount","Count",strTemp,"C:\\usefile.ini");
運行結果: C 盤(pán)下創(chuàng )建了 usefile.ini 文件,文件內容如下:
[UseFileName]
FileName0=File0.txt
FileName1=File1.txt
FileName2=File2.txt
FileName3=File3.txt
FileName4=File4.txt
FileName5=File5.txt
[FileCount]
Count=6
實(shí)例 4 :從 INI 文件讀出信息
程序將 C:\student.ini 文件中的信息讀出到程序中。
步驟:如前,在相應的 button 按鈕響應事件函數處,添加如下代碼:
CString strTemp,strTempA;
int i;
int nCount;
nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile.ini");
for(i=0;i<nCount;i++)
{
strTemp.Format("%d",i);
strTemp="FileName"+strTemp;
::GetPrivateProfileString("UseFileName",strTemp,"default.txt",strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile.ini");
//strTempA 中就存儲了文件名
}
運行結果:可以通過(guò)設置斷點(diǎn),來(lái)查看 strTemp 和 strTempA 的內容。
聯(lián)系客服
微信登錄中...
請勿關(guān)閉此頁(yè)面
