zoukankan      html  css  js  c++  java
  • 文件读取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
    文件和读取
    ---------------------------------

  • 相关阅读:
    test
    VS dll 引用依赖
    Git配置
    编码--文字输入的前因后果
    base64相关
    异或
    UNION / UNION ALL 区别
    数据库使用规范
    chrome插件开发学习(一)
    缓存穿透 缓存雪崩 缓存并发
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3113075.html
Copyright © 2011-2022 走看看