none
wince下ini文件读取 RRS feed

  • 问题

  • 前一段时间在我的blog上,我已经公开了.net(c#)和dos下的ini文件读取,现在我公开一下用EVC实现的ini读取代码,该代码是优化后的代码,效率还是比较高的,由我的一位同事编写完成的。

    程序块

    /* GetPrivateProfileString_fast 读取INI文件优化版
       算法描述:
       step 1 : 首先,搜索 [AppName] 的位置,记为 A ;
       step 2 : 然后,从 A 开始,搜索 KeyName 的出现位置,如果没有找到,那么失败返回;
       step 3 : 如果找到了 KeyName ,那么判断,该位置的 KeyName 是不是左邻 “回车换行”
       右邻 “=”,如果满足条件,那么判断 [AppName] 和 KeyName之间是否出现了
       “[”,如果出现了,那么说明找到的这个key不属于[AppName]段,那么搜索已
       经越段了,失败返回;如果以上条件都满足了,那么说明是真正找到了目标,
       接下来,就是拷贝字符串并返回了;如果左邻回车换行右邻“=”的条件没有满足,
       那么 A<- KeyName位置+1,跳转到 step 2 继续执行;
    */
    DWORD CYFIOMEM::GetPrivateProfileString(LPCTSTR lpAppName,
               LPCTSTR lpKeyName,
               LPCTSTR lpDefault,
               LPTSTR lpReturnedString,
               DWORD nSize,
               LPCTSTR lpFileName )
    {
      CFile iniFile;               //文件读写类
      PBYTE pFileBuf;              //文件缓冲区
      CString szBuf;              
      DWORD dwLength;              //文件长度
      long AppNamePos=-1;          //AppName出现的位置;
      long KeyPos=-1;              //KeyName出现的位置;
      long i,j,k,l;       
      const short ASC_TAB =9;      //Tab 键、空格键的ASC码;
      const short ASC_SPACE =32;  
      bool LeftOK,RightOK;         //标志,用来判断是否 左邻回车换行、右邻 “=”
      long EqualCharPos;           //“=” 的位置;

      //用来接收结果的是个空指针,那么无法接收结果,返回;
      if( lpReturnedString == NULL)return 0;

      //如果有默认字符串,那么拷贝默认字符串
      if( lpDefault ) {_tcscpy( lpReturnedString,lpDefault ); }
      //没有默认的,直接拷贝个结束符
      else {_tcscpy( lpReturnedString,TEXT( "\0" )); }
     
      //没有指定文件名
      if (lpFileName == NULL )
      {return _tcslen( lpReturnedString );} 
      //打开文件,如果失败则返回;
      if(!iniFile.Open(lpFileName, CFile::modeRead))
      {return _tcslen( lpReturnedString );}
     
      dwLength = iniFile.GetLength();//获得文件字节数

      //如果文件0字节则返回
      if (dwLength == 0) { return _tcslen( lpReturnedString );}

      pFileBuf = new BYTE[dwLength + 2]; //分配缓冲区
      if (pFileBuf == NULL) { return _tcslen( lpReturnedString );}//失败则返回
     
      memset(pFileBuf, 0x0, dwLength + 2);//缓冲区充0;

      iniFile.Read((void *)pFileBuf, dwLength); //把文件数据读取到缓冲区;
      iniFile.Close();//关闭文件
     
      if (pFileBuf[0] == 0xFF && pFileBuf[1] == 0xFE) {szBuf = (LPCWSTR)(pFileBuf + 2);}
      else
      {
       unsigned short * pszWideChar = new unsigned short[dwLength + 1];
       MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pFileBuf, dwLength,pszWideChar, dwLength);
       szBuf = pszWideChar;
       delete[] pszWideChar;
      }
      delete[] pFileBuf;//删除文件缓冲区;

     CString sAppName;
     sAppName.Format (_T("%s"),lpAppName);

     AppNamePos = szBuf.Find (_T("[") + sAppName + _T("]"));//找[AppName]的位置

     if (AppNamePos <0) return _tcslen( lpReturnedString );//没有则返回

     CString sKeyName;
     sKeyName.Format (_T("%s"),lpKeyName);

     long FindStart = AppNamePos+2;//先从[AppName]的位置找;

     while(1)
     {
      KeyPos = szBuf.Find(sKeyName,FindStart); //找KeyName的位置;
      if (KeyPos <0 ) return _tcslen( lpReturnedString ); //没找到,返回默认字符串;
       
      LeftOK =false;//一个bool 标志,表示是否左邻 回车换行;

      for (i = KeyPos-1;i>0 ;i--)
      {
       if ( szBuf.GetAt (i)== ASC_TAB || szBuf.GetAt (i) == ASC_SPACE)
       {/*忽略 空格 和 Tab*/}
       else
       {
        if (szBuf.GetAt (i)==10 && szBuf.GetAt (i-1)== 13)
        {     
         LeftOK =true;
         break;
        }
        else
         break;
       }
      }

      RightOK = false;
      for (i = KeyPos + sKeyName.GetLength ();i<= szBuf.GetLength ()-1;i++)
      {
       if (szBuf.GetAt(i)== ASC_TAB || szBuf.GetAt (i) == ASC_SPACE)
       {/*忽略 空格 和 Tab*/}
       else
       {
        if ( szBuf.GetAt (i) == '=' )
        {
         RightOK =true;
         EqualCharPos =i;//记下等于号的位置,待会儿要用;
         break;
        }
        else
         break;
       }
      }

      k=szBuf.Find ('[',AppNamePos+1);//寻找‘[’
      if (k< KeyPos  && k >-1 )//如果找到了[,并且在KeyName和AppName之间,说明
       //中间有另外的段,KeyName不属于AppName段。已经找过界了,失败返回;
        return _tcslen( lpReturnedString );

      if (LeftOK && RightOK)//如果满足条件,那么可以拷贝字符串并返回了;
      {
       j= 0;
       if (nSize ==0 )return 0;//目标缓冲区不够用;
       for (i =EqualCharPos+1;i<=(long)dwLength;i++)
       {
        if ((long)dwLength-1 < i)//到了文件末尾
        {
         lpReturnedString[j]=0;//送结束符
         for (l= j-1 ; l>= 0 ;l--)//回溯,去掉末尾的空格和tab
         { 
          if (ASC_TAB == lpReturnedString[l]   ||
           ASC_SPACE == lpReturnedString[l] )
           lpReturnedString[l] =0;
          else
           break;
         }
         return _tcslen( lpReturnedString );//成功返回
        }

        if (szBuf.GetAt(i) ==13 && szBuf.GetAt (i+1) ==10 )//碰到了回车换行;
        {
         lpReturnedString[j]=0;//送结束符
         for (l= j-1 ; l>= 0 ;l--)//回溯,去掉末尾的空格和tab
         { 
          if (ASC_TAB == lpReturnedString[l]   ||
           ASC_SPACE == lpReturnedString[l] )
           lpReturnedString[l] =0;
          else
           break;
         }
         return _tcslen( lpReturnedString );//成功返回;
        }

        lpReturnedString[j]= szBuf.GetAt (i); //拷贝字符;
        if (++j > (long)nSize -1)
         return 0;//目标缓冲区不够用;
       }
      }

      FindStart = KeyPos+1;//如果不满足条件,那么后移查找位置,继续查找;
     }

     return _tcslen( lpReturnedString );
    }

     

     


    2007年10月23日 14:52
    版主

答案

全部回复