文件读取ini文件另一种读取办法

时间紧张,先记一笔,后续优化与完善。

    Windows下的ini文件的读取可以应用系统提供的api来实现

    

    GetPrivateProfileString

    GetPrivateProfileInt

    ...

    现实应用中, 如果不应用一种同一的方法来包装一下会让源代码看起来很乱。

    所以,须要计划一个便利,雅观,直观的配置文件操作类!

    

    准则是代码难看,轻易维护

    

    需求:

    直观的调用形式

    实现潜规则

    满足各类数据(实现api经常应用的数据类型)

    

    

解释:

    

  • 直观的调用形式是什么意思
    以减少键盘输入和见文知意为准则的计划方式,把长函数名变为符号。用符号来表示操作
  • 潜规则
    在配置ini访问中的潜规则是
    1. Wiki上对ini的定义
        INI文件有节的观点节用 [] 包围,类似数据中的表名称,如
    [startup]

        名称/值对,类似数据库表中的字段,如
    TargetIP=10.0.0.1

        注释, 以";"为注释的开始,到行尾,如
    MenuOne=File...    ; 菜单的第一项文字描述

    2. Windows系统中操作ini文件时有#扫尾的行是疏忽的,如:
    #对打印机的设置

     3. 可配置是否疏忽Key的大小写
     4. 符合语义的读取和写入
在windows api下GetPrivateProfile/WritePrivateProfileXXXX在调用该方法时同步执行对ini文件的操作
  • 满足各类数据,在ini中经常应用的数据有两种,字符串整型数据,满足所有数据类型明显不现实,可以在之后根据不同须要进行扩展
计划应用方法:
1.  读取
CIniAccessor accessor(_T("config.ini"));
std::wstring strMenuOne = accessor[_T("startup")][_T("MenuOne")](_T("DefaultMenuItem"));
2. 写入
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();      // 写入磁盘



    

上面是数据结构
    每日一道理
无知者为梦想中的虚幻而苦苦等待,换回的不是所求的,而是岁月在脸上留下的印痕,一事无成的人一生便是虚度。生活中,与其花时间去等待,不如加快步伐去追寻理想,试着与时间赛跑,也许身躯、心理会感到劳累,但这样的生活毕竟是充实的。
  1. 基础类
    typedef struct tagAccessorData
    {
    	union VALUETYPE
    	{
    		LONG longValue;
    		TCHAR * pszValue;
    	}value;
    	enum{TYPE_EMPTY, TYPE_LONG, TYPE_CHAR}valuetype;
    	tagAccessorData():valuetype(TYPE_EMPTY){}
    }ACCESSORDATA;



  2. 辅助工具类
    
    
    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 open
    			GENERIC_READ,          // open for reading
    			FILE_SHARE_READ,       // share for reading
    			NULL,                  // default security
    			OPEN_EXISTING,         // existing file only
    			FILE_ATTRIBUTE_NORMAL, // normal file
    			NULL);                 // no attr. template
    
    
    		if (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 = value
    					TCHAR 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 open
    			GENERIC_WRITE,          // open for reading
    			FILE_SHARE_WRITE,       // share for reading
    			NULL,                  // default security
    			OPEN_ALWAYS,         // existing file only
    			FILE_ATTRIBUTE_NORMAL, // normal file
    			NULL);                 // no attr. template
    
    
    		if (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;
    	}
    };


  3. 访问类
    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];
    	}
    };
  4. 访问类
    typedef TIniAccessor<> CIniAccessor;



文章结束给大家分享下程序员的一些笑话语录: 自行车
一个程序员骑着一个很漂亮的自行车到了公司,另一个程序员看到了他,问 到,“你是从哪搞到的这么漂亮的车的?”
骑车的那个程序员说, “我刚从那边过来, 有一个漂亮的姑娘骑着这个车过来, 并停在我跟前,把衣服全脱了,然后对我说,‘你想要什么都可以’”。
另一个程序员马上说到, “你绝对做了一个正确的选择, 因为那姑娘的衣服你 并不一定穿得了”。

--------------------------------- 原创文章 By
文件和读取
---------------------------------

原文地址:https://www.cnblogs.com/jiangu66/p/3113075.html