时间紧张,先记一笔,后续优化与完善。
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
文件和读取
---------------------------------