本文主要是介绍PoEdu-Windows班-006 INI文件操作API,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
INI文件简介
在我们写程序时,总有一些配置信息需要保存下来,以便在下一次启动程序完成初始化,这实际上是一种类持久化。将一些信息写入INI文件(initialization file)中,可完成简单的持久化支持。
Windows提供了API接口用于操作INI文件,其支持的INI文件格式一般如下:
===============================
[Section1]
Key11=value11
Key12=value12
[Section2]
Key21=value21
Key22=value22
...
[SectionN]
KeyN1=valueN1
KeyN2=valueN2
===============================
一般一个INI文件可有N个节,每节可有n个键名及值对应,每个键名及其值以等式形式占一行。
一般键的名称可任取,不过建议用有意义的字符及词构成。值一般可为整数和字符串,其它类型要进行转换。
常见的系统配置文件:
C:/boot.ini
C:/WINDOWS/win.ini
C:/WINDOWS/system.ini
C:/WINDOWS/desktop.ini
C:/WINDOWS/Resources/Themes/WindowsClassic.theme
注意,字符串存贮在INI文件中时没有引号;key和value之间的等号前后不容空格;注释以分号“;”开头。
VC中操作INI文件的API
(1)操作系统配置文件Win.ini的函数:
函数名 | 功能 |
GetProfileSection | 读取win.ini中指定节lpAppName中所有键名及其值。lpReturnedString字符串形式如下: Key1=Value1/0Key2=Value2/0…KeyN=ValueN/0/0 |
GetProfileString | 读取win.ini中指定节lpAppName中键名为lpKeyName对应变量的字符串值。 |
GetProfileInt | 读取win.ini中指定节lpAppName中键名为lpKeyName对应变量的整数值。 |
|
|
WriteProfileSection | 写(替换)win.ini中指定节lpAppName中的键值。 lpString字符串形式同GetProfileSection中的lpReturnedString。 |
WriteProfileString | 写(替换)win.ini中指定节lpAppName中键名为lpKeyName对应变量的字符串值。 |
(2)操作用户自定义配置文件(PrivateProfile.ini)的函数:
函数名 | 功能 |
GetPrivateProfileSectionNames | 读取lpFileName指定的配置文件中所有的节名。lpszReturnBuffer字符串形式如下: Section1/0Section2/0…SectionN/0/0 |
GetPrivateProfileSection | 同GetProfileSection。 |
GetPrivateProfileString | 同GetProfileString。 |
GetPrivateProfileInt | 同GetProfileInt |
GetPrivateProfileStruct | 须同WritePrivateProfileStruct配套使用。 |
|
|
WritePrivateProfileSection | 同WriteProfileSection |
WritePrivateProfileString | 同WriteProfileString |
WritePrivateProfileStruct | 不常用。 |
注意:
(1)使用得最频繁的是 GetPrivateProfileString 和 WritePrivateProfileString,没有WriteProfileInt/WritePrivateProfileInt函数。
(2)Get系列读取节键值,如果文件路径有误或节键名不对则返回设定的默认值。
(3)访存自定义配置文件时,文件路径lpFileName必须完整,文件名前面的各级目录必须存在。如果lpFileName文件路径不存在,则函数返回FALSE,GetLastError() = ERROR_PATH_NOT_FOUND。如果路径正确,但是文件不存在,则该函数将先创建该文件。如果路径及文件存在,则在现有ini文件基础上进行读写。
如果 lpFileName 只指定文件名而没有路径的话,调用API将会去 Windows 的安装目录去查找而不会在当前目录查找。
(4)要对调用API的模块(exe)所在目录下进行配置文件操作,可使用形如“.//config.ini”的相对路径,注意转义符。
(5)调用WritePrivateProfileSection,若参数三 lpString为NULL,则可将对应section的全部内容清空;调用WritePrivateProfileString,若参数三 lpString为NULL,则可将对应key删除。
跨平台配置文件
INI文件本质是对文件和字符串的处理,因此在跨平台项目中的配置文件可以基于<stdio.h>中的标C文件FILE,然后实现像类似以上对节([Section])、键(Key)和值(Value)的字符串读写功能。
鉴于XML的树形描述层次结构性清晰,现在很多软件都大面积使用XML文件进行配置,如QQ的全局配置文件C:/Program Files/Tencent/QQ/gf-config.xml。Java程序的配置文件基本都使用XML格式,C++中并没有操作XML文件的标准库。
在C/C++程序中要使用XML做为配置文件,涉及到XML的解析。Windows平台可使用MsXml对XML进行解析,参考《MsXml创建和解析XML示例》,跨平台可以考虑自己实现,或使用C++ BOOST正则表达式,或选择Free C or C++XML Parser Libraries,如XmlParser、TinyXML、CMarkup、libxml等。
CIniFile类
以下提供对Windows操作INI文件的API的简单封装类CIniFile。
1. // IniFile.h
2. #ifndef __INIFILE_H__
3. #define __INIFILE_H__
4.
5. class CIniFile
6. {
7. public:
8. CIniFile();
9. CIniFile(LPCTSTR szFileName);
10. virtual ~CIniFile();
11.
12. public:
13. // Attributes
14. void SetFileName(LPCTSTR szFileName);
15.
16. public:
17. // Operations
18. BOOL SetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, int nKeyValue);
19. BOOL SetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, LPCTSTR lpszKeyValue);
20.
21. DWORD GetProfileSectionNames(CStringArray& strArray); // 返回section数量
22.
23. int GetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName);
24. DWORD GetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, CString& szKeyValue);
25.
26. BOOL DeleteSection(LPCTSTR lpszSectionName);
27. BOOL DeleteKey(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName);
28.
29. private:
30. CString m_szFileName; // .//Config.ini, 如果该文件不存在,则exe第一次试图Write时将创建该文件
31.
32. UINT m_unMaxSection; // 最多支持的section数(256)
33. UINT m_unSectionNameMaxSize; // section名称长度,这里设为32(Null-terminated)
34.
35. void Init();
36. };
37.
38. #endif
39.
40. // IniFile.cpp
41. #include "IniFile.h"
42.
43. void CIniFile::Init()
44. {
45. m_unMaxSection = 512;
46. m_unSectionNameMaxSize = 33; // 32位UID串
47. }
48.
49. CIniFile::CIniFile()
50. {
51. Init();
52. }
53.
54. CIniFile::CIniFile(LPCTSTR szFileName)
55. {
56. // (1) 绝对路径,需检验路径是否存在
57. // (2) 以"./"开头,则需检验后续路径是否存在
58. // (3) 以"../"开头,则涉及相对路径的解析
59.
60. Init();
61.
62. // 相对路径
63. m_szFileName.Format(".//%s", szFileName);
64. }
65.
66. CIniFile::~CIniFile()
67. {
68.
69. }
70.
71. void CIniFile::SetFileName(LPCTSTR szFileName)
72. {
73. m_szFileName.Format(".//%s", szFileName);
74. }
75.
76. DWORD CIniFile::GetProfileSectionNames(CStringArray &strArray)
77. {
78. int nAllSectionNamesMaxSize = m_unMaxSection*m_unSectionNameMaxSize+1;
79. char *pszSectionNames = new char[nAllSectionNamesMaxSize];
80. DWORD dwCopied = 0;
81. dwCopied = ::GetPrivateProfileSectionNames(pszSectionNames, nAllSectionNamesMaxSize, m_szFileName);
82.
83. strArray.RemoveAll();
84.
85. char *pSection = pszSectionNames;
86. do
87. {
88. CString szSection(pSection);
89. if (szSection.GetLength() < 1)
90. {
91. delete[] pszSectionNames;
92. return dwCopied;
93. }
94. strArray.Add(szSection);
95.
96. pSection = pSection + szSection.GetLength() + 1; // next section name
97. } while (pSection && pSection<pszSectionNames+nAllSectionNamesMaxSize);
98.
99. delete[] pszSectionNames;
100. return dwCopied;
101. }
102.
103. DWORD CIniFile::GetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, CString& szKeyValue)
104. {
105. DWORD dwCopied = 0;
106. dwCopied = ::GetPrivateProfileString(lpszSectionName, lpszKeyName, "",
107. szKeyValue.GetBuffer(MAX_PATH), MAX_PATH, m_szFileName);
108. szKeyValue.ReleaseBuffer();
109.
110. return dwCopied;
111. }
112.
113. int CIniFile::GetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName)
114. {
115. int nKeyValue = ::GetPrivateProfileInt(lpszSectionName, lpszKeyName, 0, m_szFileName);
116.
117. return nKeyValue;
118. }
119.
120. BOOL CIniFile::SetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, LPCTSTR lpszKeyValue)
121. {
122. return ::WritePrivateProfileString(lpszSectionName, lpszKeyName, lpszKeyValue, m_szFileName);
123. }
124.
125. BOOL CIniFile::SetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, int nKeyValue)
126. {
127. CString szKeyValue;
128. szKeyValue.Format("%d", nKeyValue);
129.
130. return ::WritePrivateProfileString(lpszSectionName, lpszKeyName, szKeyValue, m_szFileName);
131. }
132.
133. BOOL CIniFile::DeleteSection(LPCTSTR lpszSectionName)
134. {
135. return ::WritePrivateProfileSection(lpszSectionName, NULL, m_szFileName);
136. }
137.
138. BOOL CIniFile::DeleteKey(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName)
139. {
140. return ::WritePrivateProfileString(lpszSectionName, lpszKeyName, NULL, m_szFileName);
141. }
这篇关于PoEdu-Windows班-006 INI文件操作API的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!