zoukankan      html  css  js  c++  java
  • VC版的IniFile

     

    1、这个IniFile是参考Delphi的Inifile来实现的。总共包括三个类:CCustomIniFile, CIniFile和CMemIniFile

    其中CCustomIniFile是个抽象类,CIniFile和CMemIniFile是两个具体实现

    2、CIniFile通过调用WINDOWS的GetPrivateProfileStringA和WritePrivateProfileStringA两个接口来实现。

    其键值的大小有65535的限制;

    3、而CMemIniFile则是存手工打造。

    其基本思想就是,在创建该对象时,一次性将文件内容读取到内存中,以后所有的操作都在内存中进行。在读操作较多的情况下,使用这个实现可以具有较好的性能。当然,这个类也是允许有写操作的,不过所有的写操作如果要保存到文件中,需要调用其UpdateFile接口。

    另外,该类的构造函数中还提供一个属性bCaseSensitive,用于设置是否大小写敏感,如果设置为false,则所有的section和key都不区分大小写。

    其键值大小没有65535的限制;

    有关细节可以参考源码。

    // IniFile.h: interface for the CIniFile class.

    //

    //////////////////////////////////////////////////////////////////////

     

    #if !defined(AFX_INIFILE_H__8EB2CF67_E87C_45B4_BBF9_29981D7CE07B__INCLUDED_)

    #define AFX_INIFILE_H__8EB2CF67_E87C_45B4_BBF9_29981D7CE07B__INCLUDED_

     

    #if _MSC_VER > 1000

    #pragma once

    #endif // _MSC_VER > 1000

     

    #pragma warning(disable: 4786)

    #include <vector>

    #include <map>

    #include <set>

     

    /************************************************************************/

    /* ClassName : CCustomIniFile

    /* Author     : xxx

    /* Date           : 2008/12/17

    /* Description    : 基类

    /************************************************************************/

    class CCustomIniFile 

    {

    public:

        CCustomIniFile(CString const& fileName="");

        virtual ~CCustomIniFile();

     

    protected:

        /// <summary>

        /// 文件名

        /// </summary>

        CString m_fileName;

    public:   

        /// <summary>

        /// 清空该INI文件的内容

        /// </summary>

        virtual void Reset();

     

        /// <summary>

        /// 获取指定的键的字符串值

        /// </summary>

        virtual CString GetString(CString const& section, CString const& key, CString const& defaultValue="")=0;

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetString(CString const& section, CString const& key, CString const& value)=0;

       

        /// <summary>

        /// 取得section的key键的字符串,并转换为int

        /// </summary>

        virtual int GetInt(CString const& section, CString const& key, int defaultValue=0);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetInt(CString const& section, CString const& key, int value);

          

        /// <summary>

        /// 取得section的key键的字符串,并转换为unsigned long

        /// </summary>

        virtual unsigned long GetUnsignedlong(CString const& section, CString const& key, unsigned long defaultValue = 0);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetUnsignedLong(CString const& section, CString const& key, unsigned long value);

       

        /// <summary>

        /// 取得section的key键的字符串,并转换为byte

        /// </summary>

        virtual byte GetByte(CString const& section, CString const& key, byte defaultValue = 0);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetByte(CString const& section, CString const& key, byte value);

     

        /// <summary>

        /// 获取bool量

        /// </summary>

        virtual bool GetBool(CString const& section, CString const& key, bool defaultValue = false);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内,true为,false 为

        /// </summary>

        virtual void SetBool(CString const& section, CString const& key, bool value);

     

        /// <summary>

        /// 取得section的key键的字符串,并转换为float

        /// </summary>

        virtual float GetFloat(CString const& section, CString const& key, float defaultValue = 0.0);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetFloat(CString const& section, CString const& key, float value);

     

        /// <summary>

        /// 取得section的key键的字符串,并转换为double

        /// </summary>

        virtual double GetDouble(CString const& section, CString const& key, double defaultValue = 0.0);

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetDouble(CString const& section, CString const& key, double value);

     

        /// <summary>

        /// 取得section的key键下的时间,并转换为时间,时间的格式为:2006-10-10 01:02:03或-10-10 1:2:3

        /// </summary>

        virtual CTime GetDateTime(CString const& section, CString const& key, CTime defaultValue= CTime());

       

        /// <summary>

        /// 为section的key键设置时间

        /// </summary>

        virtual void SetDateTime(CString const& section, CString const& key, CTime value);

     

        /// <summary>

        /// 取得section的key键下的日期,并转换为CTime,时间的格式为:2006-10-10 00:00:00

        /// </summary>

        virtual CTime GetDate(CString const& section, CString const& key, CTime defaultValue= CTime());

     

        /// <summary>

        /// 为section的key键设置日期,字符串的格式为2006-10-10

        /// </summary>

        virtual void SetDate(CString const& section, CString const& key, CTime value);

     

        /// <summary>

        /// 取得section的key键下的日期,并转换为CTime,时间字符串的格式为: 01:11:22

        /// </summary>

        virtual CTime GetTime(CString const& section, CString const& key, CTime defaultValue= CTime());

     

        /// <summary>

        /// 为section的key键设置日期,时间字符串的格式为: 01:11:22

        /// </summary>

        virtual void SetTime(CString const& section, CString const& key, CTime value);

     

        /// <summary>

        /// 判断指定的section是否存在

        /// </summary>

        virtual BOOL SectionExists(CString const& section);

     

        /// <summary>

        /// 判断在指定的section内的指定的key是否存在

        /// </summary>

        virtual BOOL KeyExists(CString const& section, CString const& key);

     

        /// <summary>

        /// 删除指定的键

        /// </summary>

        virtual void DeleteKey(CString const& section, CString const& key)=0;

     

        /// <summary>

        /// 删除指定的section

        /// </summary>

        virtual void DeleteSection(CString const& section)=0;

     

        /// <summary>

        /// 添加一个Section

        /// </summary>

        virtual void AddSection(CString section)=0;

     

        /// <summary>

        /// 返回该文件内的所有section列表

        /// </summary>

        virtual std::vector<CString> GetSections()=0;

     

        /// <summary>

        /// 返回指定section下的key列表

        /// </summary>

        virtual std::vector<CString> GetKeys(CString const& section)=0;

     

        /// <summary>

        /// 读取指定section内的所有值

        /// </summary>

        virtual std::vector<CString> GetSectionValues(CString const& section)=0;

     

        /// <summary>

        ///

        /// </summary>

        virtual void UpdateFile() = 0;

     

        /// <summary>

        /// 返回文件名

        /// </summary>

        CString GetFileName(){ return m_fileName; };   

     

        /// <summary>

        /// 设置文件名

        /// 文件名可以是相对路径,也可以是绝对路径

        /// 如果是相对路径,则会被自动转换为相对于当前程序的绝对路径

        /// </summary>

        virtual void SetFileName(CString const& fileName);

     

    protected:

        BOOL FileExists();

        CString GetAppPath();   

    };

     

     

    /************************************************************************/

    /* ClassName : CIniFile

    /* Author     : xxx

    /* Date           : 2008/12/17

    /* Description    : 用于读取文件的inifile类

                   1、该类所有的操作结果都马上反应到文件内,所以可以不同担心同步问题;

                   2、该类的ReadSection方法返回的是指定section的键名称列表,而不是该section下的所有内容

                   3、键值的最大长度有的限制;

    /************************************************************************/

    class CIniFile: public CCustomIniFile

    {

    public:

        CIniFile(CString const& fileName="");

        virtual ~CIniFile();

    public:

        //

        virtual CString GetString(CString const& section, CString const& key, CString const& defaultValue="");

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetString(CString const& section, CString const& key, CString const& value);

       

        /// <summary>

        /// 删除指定的键

        /// </summary>

        virtual void DeleteKey(CString const& section, CString const& key);

       

        /// <summary>

        /// 删除指定的section

        /// </summary>

        virtual void DeleteSection(CString const& section);

       

        /// <summary>

        /// 添加一个Section

        /// </summary>

        virtual void AddSection(CString section);

       

        /// <summary>

        /// 返回该文件内的所有section列表

        /// </summary>

        virtual std::vector<CString> GetSections();

       

        /// <summary>

        /// 返回指定section下的key列表

        /// </summary>

        virtual std::vector<CString> GetKeys(CString const& section);

       

        /// <summary>

        /// 读取指定section内的所有值

        /// </summary>

        virtual std::vector<CString> GetSectionValues(CString const& section);

       

        /// <summary>

        ///

        /// </summary>

        virtual void UpdateFile();

       

    private:

        std::vector<CString> BufferToStringList(char* buf, int size);

    };

     

    /************************************************************************/

    /* ClassName : CMemIniFile

    /* Author     : xxxx

    /* Date           : 2008/12/17

    /* Description    : 1、该类一次性将文件读取到内存中,以后所有的操作都在内存中进行

                   2、该类比较适合与读操作较多的情况

                   3、该类比较特殊的在于其GetSectionValues的实现,能够将一个section

                   下的所有内容读取出来,返回一个std::vector<CString>对象

                   4、该类提供了SetCaseSensitive函数,这样用户就可以选择是否大小写敏感

                   5、对该类所做的任何操作,如果要将操作结果保存到文件,则一定要调用UpdateFile()方法

                   否则所有的操作结果都只在内存中

                   6、键值的最大长度没有的限制;

    /************************************************************************/

    class CMemIniFile: public CCustomIniFile{

     

    private:

        /// <summary>

        /// 用于在map的查找时使用

        /// map的键类型为CString,比较方式为大小写不敏感

        /// </summary>

        class compare_nocase{

        public:

           compare_nocase(CString const& value):m_value(value){}

          

           template<typename T1, typename T2>

               bool operator()(std::pair<const T1, T2> elem){

               return m_value.CompareNoCase(elem.first) == 0;

           };

        private:

           CString m_value;

        };

     

    public:

        CMemIniFile(CString const& fileName="", bool bCaseSensitive = true);

        virtual ~CMemIniFile();

     

    public:

        /// <summary>

        /// 设置文件名

        /// </summary>

        virtual void SetFileName(CString const& fileName);

     

        /// <summary>

        /// 清空该INI文件的内容

        /// </summary>

        virtual void Reset();

     

        //

        virtual CString GetString(CString const& section, CString const& key, CString const& defaultValue="");

       

        /// <summary>

        /// 将value转换为字符串存储在section下的key段内

        /// </summary>

        virtual void SetString(CString const& section, CString const& key, CString const& value);

       

        /// <summary>

        /// 删除指定的键

        /// </summary>

        virtual void DeleteKey(CString const& section, CString const& key);

       

        /// <summary>

        /// 删除指定的section

        /// </summary>

        virtual void DeleteSection(CString const& section);

       

        /// <summary>

        /// 添加一个Section

        /// </summary>

        virtual void AddSection(CString section);

       

        /// <summary>

        /// 返回该文件内的所有section列表

        /// </summary>

        virtual std::vector<CString> GetSections();

       

        /// <summary>

        /// 返回指定section下的key列表

        /// </summary>

        virtual std::vector<CString> GetKeys(CString const& section);

       

        /// <summary>

        /// 读取指定section内的所有值

        /// </summary>

        virtual std::vector<CString> GetSectionValues(CString const& section);

       

        /// <summary>

        /// 将内容保存到文件内

        /// </summary>

        virtual void UpdateFile();

     

        /// <summary>

        /// 判断大小写是否敏感

        /// </summary>

        bool GetCaseSensitive(){ return m_bCaseSensitive; };

     

    private:

        /// <summary>

        /// 将文件内容读取到m_fileContent内

        /// </summary>

        void ReadfileContent();

     

        /// <summary>

        /// 生成索引

        /// </summary>

        void GenerateIndex();

     

    private:

        typedef std::map<CString, int> CSectionIndex;

        typedef std::vector<CString> CFileContent;

        typedef std::set<int> CSectionLineNumSet;

        typedef std::map<CString, CSectionIndex > CSectionKeyIndex;

        /// <summary>

        /// 文件的内容

        /// </summary>

        CFileContent m_fileContent;

       

        /// <summary>

        /// 用于存储每个section所对应的行号

        /// </summary>

        CSectionIndex m_sectionIndex;

     

        /// <summary>

        /// section的行号的集合

        /// </summary>

        CSectionLineNumSet m_sectionLineNumSet;

     

        /// <summary>

        /// 每个section下的每个键的索引

        /// </summary>

        CSectionKeyIndex m_sectionKeyIndex;

     

        /// <summary>

        /// 是否大小写敏感,这是一个只读属性

        /// </summary>

        bool m_bCaseSensitive;

    };

    #endif // !defined(AFX_INIFILE_H__8EB2CF67_E87C_45B4_BBF9_29981D7CE07B__INCLUDED_)

    // IniFile.cpp: implementation of the CIniFile class.

    //

    //////////////////////////////////////////////////////////////////////

     

    #include "stdafx.h"

    #include "IniFile.h"

    #include <algorithm>

     

    #ifdef _DEBUG

    #undef THIS_FILE

    static char THIS_FILE[]=__FILE__;

    #define new DEBUG_NEW

    #endif

     

    /////////////////////////////////////////////////////////////////////////////////

    //CCustomIniFile

    /////////////////////////////////////////////////////////////////////////////////

    CCustomIniFile::CCustomIniFile(CString const& fileName):m_fileName(fileName)

    {

     

    }

     

    CCustomIniFile::~CCustomIniFile()

    {

     

    }

     

    void CCustomIniFile::Reset()

    {

        if(m_fileName.IsEmpty())

           return;

       

        if(FileExists()) 

           ::DeleteFile(m_fileName);         

     

        CCustomIniFile::SetFileName(m_fileName);

    }

     

     

    BOOL CCustomIniFile::FileExists()

    {

        if(m_fileName.IsEmpty())

           return FALSE;

     

        CFile file;

        return file.Open(m_fileName, CFile::modeRead);      

    }

     

    CString CCustomIniFile::GetAppPath()

    {

        // 返回当前程序路径

        //不包含斜干, 如c:"PQSys

        char path[_MAX_PATH];

        memset(path,0,sizeof(path));

        ::GetModuleFileName(NULL, path, sizeof(path));

        CString strPath = path;

        int index = strPath.ReverseFind('""');

        if(index<0)

           return "";

        return strPath.Left(index);

    }

     

    void CCustomIniFile::SetFileName(CString const& fileName)

    {

        //如果是相对路径,则转换为绝对路径

        if(fileName.IsEmpty())

           return;

     

        if(fileName.Find(':') != 1)

           m_fileName = GetAppPath() + """" + fileName;

        else

           m_fileName = fileName;

       

        if(!FileExists())

        {

           try

           {

               CFile file;

               file.Open(m_fileName, CFile::modeCreate);

           }

           catch (CException* e)

           {

               UNUSED_ALWAYS(e);

               TRACE("CIniFile::SetFileName() Failed!, fileName = %s", fileName);

           }     

        }

    }

     

    int CCustomIniFile::GetInt(CString const& section, CString const& key, int defaultValue)

    {

        CString strValue = GetString(section, key);

        if(strValue.IsEmpty())

           return defaultValue;

        int value(defaultValue);

        try

        {     

           value = atoi(strValue.GetBuffer(strValue.GetLength()));

           strValue.ReleaseBuffer(strValue.GetLength());

        }

        catch (...)

        {     

           strValue.ReleaseBuffer(strValue.GetLength());

           return value;

        }

        return value;

    }

     

    //

    void CCustomIniFile::SetInt(CString const& section, CString const& key, int value)

    {

        CString strValue;

        strValue.Format("%d", value);

        SetString(section, key, strValue);

    }

     

     

     

    unsigned long CCustomIniFile::GetUnsignedlong(CString const& section, CString const& key, unsigned long defaultValue)

    {

        CString strValue = GetString(section, key);

        if(strValue.IsEmpty())

           return defaultValue;

        unsigned long value(defaultValue);

        try

        {     

           int base(10);

           char* pBuffer = strValue.GetBuffer(strValue.GetLength());

           char* pBufferEnd = &pBuffer[strValue.GetLength()-1];

           value = strtoul(pBufferEnd, &pBufferEnd,base);

           strValue.ReleaseBuffer(strValue.GetLength());

        }

        catch (CException* e)

        {

           UNUSED_ALWAYS(e);

           strValue.ReleaseBuffer(strValue.GetLength());

           return value;

        }

        return value;

    }

     

    void CCustomIniFile::SetUnsignedLong(CString const& section, CString const& key, unsigned long value)

    {

        CString strValue;

        strValue.Format("%d", value);

        SetString(section, key, strValue);

    }

     

     

    byte CCustomIniFile::GetByte(CString const& section, CString const& key, byte defaultValue)

    {

        return (byte)GetInt(section, key, defaultValue);

    }

     

    void CCustomIniFile::SetByte(CString const& section, CString const& key, byte value)

    {

        SetInt(section, key, value);

    }

     

    bool CCustomIniFile::GetBool(CString const& section, CString const& key, bool defaultValue)

    {

        if(GetInt(section, key, defaultValue))

           return true;

        return false;

    }

     

    void CCustomIniFile::SetBool(CString const& section, CString const& key, bool value)

    {

        SetInt(section, key, value);

    }

     

    float CCustomIniFile::GetFloat(CString const& section, CString const& key, float defaultValue)

    {

        return (float)GetDouble(section, key, defaultValue);

    }

     

    void CCustomIniFile::SetFloat(CString const& section, CString const& key, float value)

    {

        CString strValue;

        strValue.Format("%f", value);

        SetString(section, key, strValue);

    }

     

    double CCustomIniFile::GetDouble(CString const& section, CString const& key, double defaultValue)

    {

        CString strValue = GetString(section, key);

        if(strValue.IsEmpty())

           return defaultValue;

        int value(defaultValue);

        try

        {            

           value = atof(strValue.GetBuffer(strValue.GetLength()));

           strValue.ReleaseBuffer(strValue.GetLength());

        }

        catch (CException* e)

        {

           UNUSED_ALWAYS(e);

           strValue.ReleaseBuffer(strValue.GetLength());

           return value;

        }

        return value;

    }

     

    void CCustomIniFile::SetDouble(CString const& section, CString const& key, double value)

    {

        CString strValue;

        strValue.Format("%f", value);

        SetString(section, key, strValue);

    }

     

    CTime CCustomIniFile::GetDateTime(CString const& section, CString const& key, CTime defaultValue)

    {

        //兼容-1-2 10:2:3,2005-01-02 10:02:03两种格式

        //也可以只有日期没有时间,如-01-02或2005-1-2

        CString strValue = GetString(section, key);

        if(strValue.IsEmpty())

           return defaultValue;

        strValue.TrimLeft();

        strValue.TrimRight();

        try

        {

           //year

           int monthPos = strValue.Find('-');

           if(monthPos == -1)

               return defaultValue;

           int nYear = atoi(strValue.Mid(0,monthPos));

           //month

            int dayPos = strValue.Find('-',monthPos+1);

           if(dayPos == -1)

               return defaultValue;

           int nMonth = atoi(strValue.Mid(monthPos+1,dayPos - monthPos -1));

           //day

           int hPos = strValue.Find(' ',dayPos +1);

           if(hPos == -1)

               return defaultValue;

           int nDay = atoi(strValue.Mid(dayPos+1,hPos - dayPos -1));

           //hour

           int mPos = strValue.Find(':',hPos +1 );

           if(mPos == -1)

               return CTime(nYear, nMonth, nDay,0, 0, 0);

           int nHour = atoi(strValue.Mid(hPos+1,mPos-hPos -1));

           //minute

           int sPos = strValue.Find(':',mPos+1);

           if(sPos== -1)

               return CTime(nYear, nMonth, nDay,0, 0, 0);

           int nMinute = atoi(strValue.Mid(mPos+1,sPos - mPos -1));

           //second

           int nSecond = atoi(strValue.Mid(sPos+1,strValue.GetLength() - sPos -1));

          

           return CTime(nYear,nMonth,nDay,nHour,nMinute,nSecond);    

        }

        catch (CException* e)

        {

           UNUSED_ALWAYS(e);

           return defaultValue;

        }  

    }

     

    void CCustomIniFile::SetDateTime(CString const& section, CString const& key, CTime value)

    {

        CString strValue = value.Format(_T("%Y-%m-%d %H:%M:%S"));

        SetString(section, key, strValue);

    }

     

    CTime CCustomIniFile::GetDate(CString const& section, CString const& key, CTime defaultValue)

    {

        return GetDateTime(section, key, defaultValue);

    }

     

    void CCustomIniFile::SetDate(CString const& section, CString const& key, CTime value)

    {

        CString strValue = value.Format(_T("%Y-%m-%d"));

        SetString(section, key, strValue);

    }

     

    CTime CCustomIniFile::GetTime(CString const& section, CString const& key, CTime defaultValue)

    {

        //兼容:2:3,10:02:03两种格式

        CString strValue = GetString(section, key);

        if(strValue.IsEmpty())

           return defaultValue;

        strValue.TrimLeft();

        strValue.TrimRight();

        try

        {

           //hour

           int hPos = 0;

           int mPos = strValue.Find(':');

           if(mPos == -1)

               return defaultValue;

           int nHour = atoi(strValue.Mid(hPos+1,mPos-hPos -1));

           //minute

           int sPos = strValue.Find(':',mPos+1);

           if(sPos== -1)

               return defaultValue;

           int nMinute = atoi(strValue.Mid(mPos+1,sPos - mPos -1));

           //second

           int nSecond = atoi(strValue.Mid(sPos+1,strValue.GetLength() - sPos -1));

     

           return CTime(1980, 1, 1, nHour,nMinute,nSecond);

        }

        catch (CException* e)

        {

           UNUSED_ALWAYS(e);

           return defaultValue;

        }

    }

     

    void CCustomIniFile::SetTime(CString const& section, CString const& key, CTime value)

    {

        CString strValue = value.Format(_T("%H:%M:%S"));

        SetString(section, key, strValue);

    }

     

    BOOL CCustomIniFile::SectionExists(CString const& section)

    {

        std::vector<CString> sectionList = GetSections();   

        for (std::vector<CString>::iterator it = sectionList.begin(); it!= sectionList.end(); ++it)

        {

           if(section == *it)

               return TRUE;

        }

        return FALSE;

    }

     

    BOOL CCustomIniFile::KeyExists(CString const& section, CString const& key)

    {

        std::vector<CString> keyList = GetKeys(section);

        for (std::vector<CString>::iterator it = keyList.begin(); it!= keyList.end(); ++it)

        {

           if(key == *it)

               return TRUE;

        }

        return FALSE;

    }

     

    /////////////////////////////////////////////////////////////////////////////////

    //CIniFile

    /////////////////////////////////////////////////////////////////////////////////

    #define BUFFER_SIZE 65536

    char buffer[BUFFER_SIZE];

    CIniFile::CIniFile(CString const& fileName):CCustomIniFile(fileName)

    {

        SetFileName(fileName);

    }

     

    CIniFile::~CIniFile()

    {

     

    }

     

    CString CIniFile::GetString(CString const& section, CString const& key, CString const& defaultValue)

    {

        //如果键值是用引号括起来的,则返回值中将不包含引号

        //比如key = "value"

        //或 key = 'value'

        //则返回值将是value 

       

        memset(buffer,0,BUFFER_SIZE);

        int size = GetPrivateProfileStringA(section, key, defaultValue, buffer, BUFFER_SIZE, m_fileName); 

        return buffer;

    }

     

    void CIniFile::SetString(CString const& section, CString const& key, CString const& value)

    {

        //对于两头含有空格的值,如果不用引号括起来,

        //则在读取的时候,这些空格会被自动去掉

        int strLen = value.GetLength();

        CString tempValue(value);

        if( strLen > 0 && (value.GetAt(0) == ' ' || value.GetAt(value.GetLength()-1) == ' '))

           tempValue.Format("""%s""", value);

       

        WritePrivateProfileStringA(section, key, tempValue, m_fileName);

    }

     

    void CIniFile::DeleteKey(CString const& section, CString const& key)

    {

        WritePrivateProfileStringA(section, key,NULL,m_fileName);

    }

     

    void CIniFile::DeleteSection(CString const& section)

    {

        WritePrivateProfileSectionA(section,NULL,m_fileName);

    }

     

    void CIniFile::AddSection(CString section)

    {

        WritePrivateProfileSectionA(section, "", m_fileName);

    }

     

    std::vector<CString> CIniFile::GetSections()

    {

        memset(buffer, 0, BUFFER_SIZE);

        int size = GetPrivateProfileSectionNamesA(buffer,BUFFER_SIZE,m_fileName);

        return BufferToStringList(buffer, size);

    }

     

    std::vector<CString> CIniFile::GetKeys(CString const& section)

    {

        memset(buffer, 0, BUFFER_SIZE);

        int size = GetPrivateProfileStringA(section, NULL, NULL, buffer, BUFFER_SIZE, m_fileName);

        return BufferToStringList(buffer, size);

    }

     

    std::vector<CString> CIniFile::GetSectionValues(CString const& section)

    {

        //该类只能这么实现

        return GetKeys(section);

    }

     

    void CIniFile::UpdateFile()

    {

        //此处参考了delphi版的TIniFile的实现

        WritePrivateProfileStringA(NULL, NULL, NULL, m_fileName);

    }

     

    std::vector<CString> CIniFile::BufferToStringList(char* buf, int size)

    {

        int iCnt, iPos;

        std::vector<CString> strList;  

        CString sectionName;

        if (size>0)

        {

           iCnt = 0; iPos = 0;                   

           for (iCnt = 0; iCnt < size; iCnt++)

           {

               if (buf[iCnt] == 0x00)

               {

                  char nameBuf[1000];

                  memset(nameBuf,0,1000);

                  memcpy(nameBuf, &buf[iPos],iCnt - iPos);

                  sectionName = nameBuf;            

                  iPos = iCnt + 1;

                  if(!sectionName.IsEmpty())

                      strList.push_back(sectionName);

               }

           }

        }

        return strList;

    }

    /////////////////////////////////////////////////////////////////////////////////

    //CMemIniFile

    /////////////////////////////////////////////////////////////////////////////////

     

    CMemIniFile::CMemIniFile(CString const& fileName, bool bCaseSensitive):CCustomIniFile(fileName),m_bCaseSensitive(bCaseSensitive)

    {

        SetFileName(fileName);

    }

     

    CMemIniFile::~CMemIniFile()

    {

     

    }

     

    void CMemIniFile::Reset()

    {

        CCustomIniFile::Reset();

        m_fileContent.clear();

        m_sectionIndex.clear();

        m_sectionKeyIndex.clear();     

    }

     

    void CMemIniFile::SetFileName(CString const& fileName)

    {

        CCustomIniFile::SetFileName(fileName);

     

        m_fileContent.clear();

        m_sectionIndex.clear();

        m_sectionKeyIndex.clear();     

       

        ReadfileContent();

        GenerateIndex();

    }

     

    void CMemIniFile::GenerateIndex()

    {

        m_sectionIndex.clear(); 

        m_sectionKeyIndex.clear();

        m_sectionLineNumSet.clear();   

        try

        {            

           int i = 0;

           CString currentSection;

           for (CFileContent::iterator it = m_fileContent.begin(); it != m_fileContent.end(); ++it,++i)

           {  

               CString& oneLine = *it;

     

               //生成section索引

               if(oneLine.Left(1) == "[" && oneLine.Right(1) == "]")

               {

                  currentSection = oneLine.Mid(1, oneLine.GetLength() - 2);

                  currentSection.TrimLeft();

                  currentSection.TrimRight();

                  m_sectionIndex[currentSection] = i;

               }

               else

               {//生成key的索引

                  int index = oneLine.Find('=', 1); //不允许键为空

                  if(index > 0)

                  {

                      CString key = oneLine.Left(index);

                      key.TrimRight();

                      m_sectionKeyIndex[currentSection][key] = i;

                  }

               }                              

           }            

          

           //生成section的行号列表

           for (CSectionIndex::iterator it2 = m_sectionIndex.begin(); it2 != m_sectionIndex.end(); ++it2)    

               m_sectionLineNumSet.insert( (*it2).second);     

        }

        catch (...)

        {

           m_sectionIndex.clear(); 

           m_sectionKeyIndex.clear();

           m_sectionLineNumSet.clear();

            return;

        }

    }

     

    void CMemIniFile::ReadfileContent()

    {

        if(m_fileName.IsEmpty())

           return;

        m_fileContent.clear();

        CStdioFile file;

        try

        {

           file.Open(m_fileName, CFile::modeRead, NULL);   

           CString oneLine;    

           while (file.ReadString(oneLine))

           {

               oneLine.TrimLeft();

               oneLine.TrimRight();

               //不允许空行

               if(oneLine.IsEmpty())

                  continue;

               m_fileContent.push_back(oneLine);        

           }  

        }

        catch (...)

        {

           m_sectionIndex.clear();

           m_fileContent.clear();

           m_sectionLineNumSet.clear();

           return;

        }

    }

     

    CString CMemIniFile::GetString(CString const& section, CString const& key, CString const& defaultValue)

    {  

        //查找section的索引

        CSectionKeyIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionKeyIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionKeyIndex.begin(), m_sectionKeyIndex.end(), compare_nocase(section));

     

        if(sectionPos == m_sectionKeyIndex.end())

           return "";

       

        //查找key的索引

        CSectionIndex& keyIndex = (*sectionPos).second;

     

        CSectionIndex::iterator keyPos;

        if(m_bCaseSensitive)

           keyPos = keyIndex.find(key);

        else

           keyPos = std::find_if(keyIndex.begin(), keyIndex.end(), compare_nocase(key));

     

        if(keyPos == keyIndex.end())

           return "";

     

        //获取键值

        CString& oneLine = m_fileContent[(*keyPos).second];

        int index = oneLine.Find('=');

        if(index <= 0)

           return "";

     

        ++index;

        return oneLine.Mid(index, oneLine.GetLength() - index);

    }

     

    void CMemIniFile::SetString(CString const& section, CString const& key, CString const& value)

    {

        //获取secion的索引

        CSectionKeyIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionKeyIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionKeyIndex.begin(), m_sectionKeyIndex.end(), compare_nocase(section));  

     

        //针对section不存在的情况

        if(sectionPos == m_sectionKeyIndex.end())

        {

           //添加一个section和key

           CString oneLine;

           oneLine.Format("[%s]", section);

           m_fileContent.push_back(oneLine);

           oneLine.Format("%s=%s", key, value);

           m_fileContent.push_back(oneLine);

           GenerateIndex();

           return;

        }

     

        //获取key的索引

        CSectionIndex& keyIndex = (*sectionPos).second;

       

        CSectionIndex::iterator keyPos;

        if(m_bCaseSensitive)

           keyPos = keyIndex.find(key);

        else

           keyPos = std::find_if(keyIndex.begin(), keyIndex.end(), compare_nocase(key));

     

        //针对key不存在的情况

        if(keyPos == (*sectionPos).second.end())

        {

           //添加一个key    

           CFileContent::iterator filePos = m_fileContent.begin();

           std::advance(filePos, m_sectionIndex[section] + 1);

           CString oneLine;

           oneLine.Format("%s=%s", key, value);

           m_fileContent.insert(filePos, oneLine);

            GenerateIndex();

           return;

        }

     

        //修改

        if((*keyPos).second < m_fileContent.size())

           m_fileContent[ (*keyPos).second].Format("%s=%s", key, value);

    }

     

    void CMemIniFile::DeleteKey(CString const& section, CString const& key)

    {

        //获取section的索引

        CSectionKeyIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionKeyIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionKeyIndex.begin(), m_sectionKeyIndex.end(), compare_nocase(section));

     

        if(sectionPos == m_sectionKeyIndex.end())

           return;

     

        //获取key的索引

        CSectionIndex& keyIndex = (*sectionPos).second;

       

        CSectionIndex::iterator keyPos;

        if(m_bCaseSensitive)

           keyPos = keyIndex.find(key);

        else

           keyPos = std::find_if(keyIndex.begin(), keyIndex.end(), compare_nocase(key));

     

        if(keyPos == keyIndex.end())

           return;

     

        //删除

        CFileContent::iterator filePos = m_fileContent.begin();

        std::advance(filePos, (*keyPos).second);

        m_fileContent.erase(filePos);

     

        //重新生成索引

        GenerateIndex();

    }

     

    void CMemIniFile::DeleteSection(CString const& section)

    {

        //获取section的索引

        CSectionIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionIndex.begin(), m_sectionIndex.end(), compare_nocase(section));

     

        if(sectionPos == m_sectionIndex.end())

           return;

     

        //获取下一个section的索引

        int firstSectionOffset = (*sectionPos).second;

        int secondSectionOffset = m_fileContent.size();

     

        CSectionLineNumSet::iterator lineNumPos = m_sectionLineNumSet.find(firstSectionOffset);

        if(lineNumPos == m_sectionLineNumSet.end())

           return;

        //查找下一个section的起始位置

        ++lineNumPos;

        if(lineNumPos != m_sectionLineNumSet.end())  

           secondSectionOffset = (*lineNumPos);

       

        CFileContent::iterator beginPos = m_fileContent.begin();

        CFileContent::iterator endPos = m_fileContent.begin();

        std::advance(beginPos, firstSectionOffset);

        std::advance(endPos, secondSectionOffset);

     

        //删除两个索引之间的内容

        m_fileContent.erase(beginPos, endPos);

     

        //重新生成索引

        GenerateIndex();

    }

     

    void CMemIniFile::AddSection(CString section)

    {

        //添加一个section

        CString oneLine;

        oneLine.Format("[%s]", section);

        m_fileContent.push_back(oneLine);

        //重新生成索引

        GenerateIndex(); 

    }

     

    std::vector<CString> CMemIniFile::GetSections()

    {

        std::vector<CString> result;

        for (CSectionIndex::iterator it = m_sectionIndex.begin(); it != m_sectionIndex.end(); ++it)

        {

           result.push_back((*it).first);

        }

        return result;

    }

     

    std::vector<CString> CMemIniFile::GetKeys(CString const& section)

    {

        //获取section的索引

        std::vector<CString> result;   

        CSectionKeyIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionKeyIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionKeyIndex.begin(), m_sectionKeyIndex.end(), compare_nocase(section));

     

        if(sectionPos == m_sectionKeyIndex.end())

           return result;

     

        //从key的索引表内获取key列表

        CSectionIndex& keyIndexs = (*sectionPos).second;

        for (CSectionIndex::iterator it = keyIndexs.begin(); it != keyIndexs.end(); ++it)  

           result.push_back( (*it).first);

     

        return result;

    }

     

    std::vector<CString> CMemIniFile::GetSectionValues(CString const& section)

    {

        std::vector<CString> result;

     

        //获取section的索引

        CSectionIndex::iterator sectionPos;

        if(m_bCaseSensitive)

           sectionPos = m_sectionIndex.find(section);

        else

           sectionPos = std::find_if(m_sectionIndex.begin(), m_sectionIndex.end(), compare_nocase(section));

     

        if(sectionPos == m_sectionIndex.end())

           return result;

     

        //获取下一个section的索引

        int firstSectionOffset = (*sectionPos).second;

        int secondSectionOffset = m_fileContent.size();

       

        CSectionLineNumSet::iterator lineNumPos = m_sectionLineNumSet.find(firstSectionOffset);

        if(lineNumPos == m_sectionLineNumSet.end())

           return result;

        //查找下一个section的起始位置

        ++lineNumPos;

        if(lineNumPos != m_sectionLineNumSet.end())  

           secondSectionOffset = (*lineNumPos);

       

        CFileContent::iterator beginPos = m_fileContent.begin();

        CFileContent::iterator endPos = m_fileContent.begin();

        std::advance(beginPos, firstSectionOffset);

        //不能包含section头本身

        ++beginPos;

        std::advance(endPos, secondSectionOffset);

        for ( ;beginPos != endPos; ++beginPos)

           result.push_back(*beginPos);   

     

        return result;

    }

     

    void CMemIniFile::UpdateFile()

    {  

        if(m_fileName.IsEmpty())

           return;

     

        CStdioFile file;

        try

        {

           CCustomIniFile::Reset();

           file.Open(m_fileName, CFile::modeWrite, NULL);

           for (CFileContent::iterator it = m_fileContent.begin(); it != m_fileContent.end(); ++it)

           {

               file.WriteString(*it + ""r"n");

           }

           file.Close();

        }

        catch (...)

        {

           m_sectionIndex.clear();

           m_fileContent.clear();

           m_sectionLineNumSet.clear();

           return;

        }  

    }

  • 相关阅读:
    键盘的出现于隐藏(解决键盘弹出时会覆盖文本框的问题,代码实现)
    UI入门指引
    OC 面试问题汇总
    通知、block
    协议和代理
    plist文件、NSUserDefault 对文件进行存储的类、json格式解析
    归档NSKeyedArchiver解归档NSKeyedUnarchiver与文件管理类NSFileManager (文件操作)
    Foundation框架下的常用类:NSNumber、NSDate、NSCalendar、NSDateFormatter、NSNull、NSKeyedArchiver
    选择器
    内存管理
  • 原文地址:https://www.cnblogs.com/strinkbug/p/1357801.html
Copyright © 2011-2022 走看看