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;



    
    
  • 相关阅读:
    VC环境OpenSSL编译笔记
    手动造工具TaskJobManage
    Java性能分析工具
    ES77
    Flink消费kafka
    阻塞对列
    C# 超时事件
    毕业前做一件事
    PID控制器——控制网络爬虫速度
    2.5 OpenEuler 中C与汇编的混合编程(选做)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3111505.html
Copyright © 2011-2022 走看看