PoEdu-Windows班-006 INI文件操作API

2024-06-14 21:08
文章标签 windows 操作 api 006 ini poedu

本文主要是介绍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,如XmlParserTinyXMLCMarkuplibxml等。

 

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; // 32UID  
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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061515

相关文章

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

一分钟带你上手Python调用DeepSeek的API

《一分钟带你上手Python调用DeepSeek的API》最近DeepSeek非常火,作为一枚对前言技术非常关注的程序员来说,自然都想对接DeepSeek的API来体验一把,下面小编就来为大家介绍一下... 目录前言免费体验API-Key申请首次调用API基本概念最小单元推理模型智能体自定义界面总结前言最

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx