文件读取ini文件另一种读取办法
时间紧张,先记一笔,后续优化与完善。
Windows下的ini文件的读取可以应用系统提供的api来实现
GetPrivateProfileString
GetPrivateProfileInt
...
现实应用中, 如果不应用一种同一的方法来包装一下会让源代码看起来很乱。
所以,须要计划一个便利,雅观,直观的配置文件操作类!
准则是代码难看,轻易维护
需求:
直观的调用形式
实现潜规则
满足各类数据(实现api经常应用的数据类型)
- 直观的调用形式是什么意思
以减少键盘输入和见文知意为准则的计划方式,把长函数名变为符号。用符号来表示操作
- 潜规则
在配置ini访问中的潜规则是
1. Wiki上对ini的定义
INI文件有节的观点节用 [] 包围,类似数据中的表名称,如[startup]
名称/值对,类似数据库表中的字段,如
TargetIP=10.0.0.1
注释, 以";"为注释的开始,到行尾,如
MenuOne=File... ; 菜单的第一项文字描述
2. Windows系统中操作ini文件时有#扫尾的行是疏忽的,如:
#对打印机的设置
- 满足各类数据,在ini中经常应用的数据有两种,字符串和整型数据,满足所有数据类型明显不现实,可以在之后根据不同须要进行扩展
CIniAccessor accessor(_T("config.ini"));
std::wstring strMenuOne = accessor[_T("startup")][_T("MenuOne")](_T("DefaultMenuItem"));
CIniAccessor accessor(_T("config.ini"));
accessor[_T("startup")][_T("TargetIP")] = _T("10.0.0.100");
3. 更新
CIniAccessor accessor(_T("config.ini"));
accessor.Update(); // 从磁盘上更新
accessor.Commit(); // 写入磁盘
无知者为梦想中的虚幻而苦苦等待,换回的不是所求的,而是岁月在脸上留下的印痕,一事无成的人一生便是虚度。生活中,与其花时间去等待,不如加快步伐去追寻理想,试着与时间赛跑,也许身躯、心理会感到劳累,但这样的生活毕竟是充实的。
- 基础类
typedef struct tagAccessorData {union VALUETYPE{LONG longValue;TCHAR * pszValue;}value;enum{TYPE_EMPTY, TYPE_LONG, TYPE_CHAR}valuetype;tagAccessorData():valuetype(TYPE_EMPTY){} }ACCESSORDATA;
- 辅助工具类
class CCoAccessorImpl:public ACCESSORDATA { private: TCHAR m_szTemp[30]; public:CCoAccessorImpl(){valuetype = TYPE_EMPTY;value.longValue = 0;}CCoAccessorImpl(const CCoAccessorImpl & acc){valuetype = acc.valuetype;if(acc.valuetype == TYPE_CHAR){value.pszValue = new TCHAR[_tcslen(acc.value.pszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(acc.value.pszValue) + 1));_tcscpy(value.pszValue, acc.value.pszValue);}else{value.longValue = acc.value.longValue;}}CCoAccessorImpl(const LONG lValue){valuetype = TYPE_LONG;value.longValue = lValue;}CCoAccessorImpl(LPCTSTR lpszValue){valuetype = TYPE_CHAR;value.pszValue = new TCHAR[_tcslen(lpszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(lpszValue) + 1));_tcscpy(value.pszValue, lpszValue);}~CCoAccessorImpl(){if(valuetype == TYPE_CHAR) delete [] value.pszValue;}CCoAccessorImpl & operator = (const CCoAccessorImpl& acc){if(valuetype == TYPE_CHAR) delete [] value.pszValue;value.longValue = 0;valuetype = acc.valuetype;if(acc.valuetype == TYPE_CHAR){value.pszValue = new TCHAR[_tcslen(acc.value.pszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(acc.value.pszValue) + 1));_tcscpy(value.pszValue, acc.value.pszValue);}else{value.longValue = acc.value.longValue;}return *this;}CCoAccessorImpl & operator = (const LONG lValue){if(valuetype == TYPE_CHAR) delete [] value.pszValue;valuetype = TYPE_LONG;value.longValue = lValue;return *this;}CCoAccessorImpl & operator = (LPCTSTR lpszValue){if(valuetype == TYPE_CHAR) delete [] value.pszValue;valuetype = TYPE_CHAR;value.pszValue = new TCHAR[_tcslen(lpszValue) + 1];ZeroMemory(value.pszValue, sizeof(TCHAR) * (_tcslen(lpszValue) + 1));_tcscpy(value.pszValue, lpszValue);return *this;}operator LPCTSTR (){ switch(valuetype){ case TYPE_LONG: return _ltot(value.longValue, m_szTemp, 10);case TYPE_CHAR: return value.pszValue;}return _T("");}operator LONG (){ switch(valuetype){case TYPE_LONG:case TYPE_EMPTY:return value.longValue;}return _ttol(value.pszValue);}CCoAccessorImpl operator ()(LPCTSTR lpsz) //default value{if(valuetype == TYPE_EMPTY) return CCoAccessorImpl(lpsz);return *this;}CCoAccessorImpl operator ()(LONG lValue) //default value{if(valuetype == TYPE_EMPTY) return CCoAccessorImpl(lValue);return *this;}}; typedef std::basic_string<TCHAR> TCharArray;struct less {bool operator()(const TCharArray& _Left, const TCharArray& _Right) const{ return _tcsicmp(_Left.c_str(), _Right.c_str()) < 0;} };template<class ValueType, BOOL bSensitive> class CKeyValueArray:public std::map<TCharArray, ValueType, less> { public:CKeyValueArray(){}~CKeyValueArray(){}ValueType & operator[](TCharArray charArray){if(!bSensitive) _tcsupr((TCHAR*)charArray.data());return std::map<TCharArray, ValueType, less>::operator[](charArray);} }; // 读文件操作 template<class Storage> struct iniparser {BOOL operator()(Storage & store, LPCTSTR lpszFilePath){HANDLE hFile = CreateFile(lpszFilePath, // file to openGENERIC_READ, // open for readingFILE_SHARE_READ, // share for readingNULL, // default securityOPEN_EXISTING, // existing file onlyFILE_ATTRIBUTE_NORMAL, // normal fileNULL); // no attr. templateif (hFile == INVALID_HANDLE_VALUE) { return FALSE; }TCHAR sz[2] = {0};DWORD dwRead = 0;TCharArray tcaLine;TCharArray tcaSectionName;struct foo{static void parse(Storage & store, TCharArray & tcaSectionName, TCharArray & tcaLine){if(!tcaLine.size()) return;// parse []TCHAR szComment[MAX_PATH] = {0};if(tcaLine.at(0) == _T('#')) return;TCharArray sSec;if(_stscanf(tcaLine.c_str(), _T("[%[^]]]"), (TCHAR*)sSec.assign(MAX_PATH,0).data())){tcaSectionName = sSec;}else{// parse key = valueTCHAR szKey[MAX_PATH] = {0};TCHAR szValue[MAX_PATH] = {0};if(2 == _stscanf(tcaLine.c_str(), _T("%[^=]=%[^\0]"), szKey, szValue)) {store[tcaSectionName][szKey] = szValue;}}}};while(ReadFile(hFile, sz, sizeof(TCHAR),&dwRead, NULL)){if(!dwRead) break;if(!(sz[0] == _T('\r') || sz[0] == _T('\n'))) {tcaLine.push_back(sz[0]);continue;}foo::parse(store, tcaSectionName, tcaLine);tcaLine.clear();tcaLine.reserve(); }CloseHandle(hFile);foo::parse(store, tcaSectionName, tcaLine); return TRUE;} }; // 写文件操作 template<class Storage> struct inipersistor {BOOL operator()(Storage & store, LPCTSTR lpszFilePath){HANDLE hFile = CreateFile(lpszFilePath, // file to openGENERIC_WRITE, // open for readingFILE_SHARE_WRITE, // share for readingNULL, // default securityOPEN_ALWAYS, // existing file onlyFILE_ATTRIBUTE_NORMAL, // normal fileNULL); // no attr. templateif (hFile == INVALID_HANDLE_VALUE) { return FALSE; }for(Storage::iterator it = store.begin();it != store.end();it++){TCharArray tcaSectionName = (*it).first;Storage::mapped_type & kva = (*it).second;DWORD dwWritten = 0;WriteFile(hFile, _T("["), sizeof(TCHAR), &dwWritten, NULL); WriteFile(hFile, tcaSectionName.c_str(), sizeof(TCHAR) * tcaSectionName.size(), &dwWritten, NULL);WriteFile(hFile, _T("]\r\n"), sizeof(TCHAR) * 3, &dwWritten, NULL);for(Storage::mapped_type::iterator itKeyVal = kva.begin();itKeyVal != kva.end();itKeyVal++){TCharArray tcaKey = (*itKeyVal).first;TCharArray tcaVal = (*itKeyVal).second;WriteFile(hFile, tcaKey.c_str(), sizeof(TCHAR) * tcaKey.size(), &dwWritten, NULL);WriteFile(hFile, _T("="), sizeof(TCHAR), &dwWritten, NULL); WriteFile(hFile, tcaVal.c_str(), sizeof(TCHAR) * tcaVal.size(), &dwWritten, NULL);WriteFile(hFile, _T("\r\n"), sizeof(TCHAR) * 2, &dwWritten, NULL);}}CloseHandle(hFile);return TRUE;} };
- 访问类
template<class ValueType = CCoAccessorImpl, BOOL bSensitive = FALSE,class Parser = iniparser<std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>,less > >,class Persistor = inipersistor<std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>,less > > > class TIniAccessor { public:private:Parser _parser;Persistor _persistor;TCharArray m_szFileName; public:TIniAccessor(LPCTSTR lpsz):_parser(Parser()),_persistor(Persistor()){m_szFileName = lpsz;_parser(m_sectionarray, m_szFileName.c_str());}BOOL Update(){return _parser(m_sectionarray, m_szFileName.c_str());}BOOL Commit(LPCTSTR lpszSaveIniFile = NULL){TCharArray tca = m_szFileName;if(lpszSaveIniFile) tca = lpszSaveIniFile;return _persistor(m_sectionarray, tca.c_str());}~TIniAccessor(){} private: typedef std::map<TCharArray, CKeyValueArray<ValueType,bSensitive>, less> SectionArray;SectionArray m_sectionarray; public: CKeyValueArray<ValueType,bSensitive> & operator [](TCharArray charArray){if(!bSensitive) _tcsupr((TCHAR*)charArray.data());return m_sectionarray[charArray];} };
- 访问类
typedef TIniAccessor<> CIniAccessor;
文章结束给大家分享下程序员的一些笑话语录: 自行车
一个程序员骑着一个很漂亮的自行车到了公司,另一个程序员看到了他,问 到,“你是从哪搞到的这么漂亮的车的?”
骑车的那个程序员说, “我刚从那边过来, 有一个漂亮的姑娘骑着这个车过来, 并停在我跟前,把衣服全脱了,然后对我说,‘你想要什么都可以’”。
另一个程序员马上说到, “你绝对做了一个正确的选择, 因为那姑娘的衣服你 并不一定穿得了”。
--------------------------------- 原创文章 By
文件和读取
---------------------------------
转载于:https://www.cnblogs.com/jiangu66/archive/2013/06/01/3113075.html
文件读取ini文件另一种读取办法相关推荐
- 使用 sed / shell 读取 ini 文件
使用 sed / shell 读取 ini 文件 动机 我决定编写一个脚本来进行干净的 macOS (BSD) / Linux 的初始设置. 我认为有一个 tsukkomi 说"现在大多数发 ...
- C# 读取ini文件 百度问问学习文档
C# 读取ini文件 10 有多个section,现想读取整个ini文件和指定section下所有内容 补充: 发布答案可以,请对准题目啊,我不要指定节点的内容,我知道!我要的是读取指定区域的内容,假 ...
- ASP读取ini文件的实现方法
INI是微软Windows操作系统中的文件扩展名.这些字母表示初始化.正如该术语所表示的,INI文件被用来对操作系统或特定程序初始化或进行参数设置.ini文件可以存储很多数据,用来配置应用软件以实现不 ...
- VS2017读取ini 文件中文乱码
[说明] 今天写项目的时候,读取ini文件时候,中文就是乱码了. 测试过,直接输出中文,是没有问题的. 因此问题就确定了是在文件的编码上. (建议各位也像我这么测试下,不然这个解决方案不一定帮得了你) ...
- VS VC 读取 INI文件
1.获取应程序同极目录下的config.ini路劲void GetConfigFilePath(char *path,int len, char *file) {char module[256] = ...
- C++读取ini文件的类
C++读取ini文件的类 取自:http://www.viksoe.dk/code/all_mfc.htm,里面有各种MFC常用的类 // Ini.h: interface for the CIni ...
- java inireader_用Java读取INI文件(带section的)
代码 #include #include int main(){ boost::property_tree::ptree m_pt, tag_setting; read_ini("confi ...
- Qt读取ini文件中文乱码问题
Qt读取ini文件中文乱码问题 方法1: QSettings settings("xxxx.ini",QSettings::IniFormat); settings.setIniC ...
- VB6读取INI文件
开发环境:VB6 程式版本更新, 读取INI文件做对比, 确认版本是否最新. 可用VB6的工具下的API检视员来自动生成API调用代码. INI文件内容: [Version] TEST=2017-11 ...
- QSettings读取ini文件,中文key方法
(吐槽:什么鬼,为啥要用中文当key???我也不知道呀) QSettings读取ini文件,其中key是中文的.例如: [单位] 1=运维检修部1(检修公司) 2=运维检修部2(检修公司)[班组] 1 ...
最新文章
- 生成html页面的ftl文件,FreeMarker生成静态HTML页面的工具类FreeMarkerUtil
- MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理
- Oracle SQL中实现indexOf和lastIndexOf功能
- 发个自己的CSS重置基础代码
- nuxt解决首屏加载慢问题_如何解决百度云盘下载速度慢的问题
- Mybatis入门-关联查询(八)
- deepin应用分发_Deepin Dock隐藏功能等功能说明
- 关于打印数组一直输出地址符号的一个解决方法
- delphi switch语句例子_Python系列之常用语句
- 自称世界上最权威监控软件FlexiSpy被黑删库,怎么做到的?
- 一篇关于arc下内存管理的老文章,包含各种冷门修饰符(关于内存),写的较好,mark...
- 台式机设成仅计算机,如何把台式电脑设置成wifi热点
- 系统动力学学习笔记一
- 甘超波:NLP表象系统
- 由ERA5逐小时数据获取逐日数据——三种方法
- Java Test Fore
- android访问win10共享文件夹,手机怎么用ES浏览器访问Win10共享文件教程
- Matlab透视变换
- 无线网络现状与发展趋势
- Java数据结构之中缀表达式转后缀表达式
热门文章
- thinkphp使用echarts_Thinkphp 与Echarts-php 使用
- java 对象克隆_JAVA对象克隆
- 剑指offer:12-17记录
- 关系数据库——mysql数据类型大总结
- 树状数组维护区间和的模型及其拓广的简单总结
- python学习实例(3)
- Mat矩阵(图像容器)的创建及CV_8UC1,CV_8UC2等参数详解
- PaperNotes(10)-Maximum Entropy Generators for Energy-Based Models
- Python中yield简单用法
- python语言print函数_Python 的 print 函数