文件读取操作的问题

来源:互联网 发布:淘宝汉服店铺推荐 编辑:程序博客网 时间:2024/05/22 02:03

ULONGLONG CmapfileDlg::Seekeditpostion(CStdioFile &EditFile)
{
 //保存从指定位置编辑之后余下的文件内容
 CString strlast;                              
 LONGLONG strlastlength = 0;
 CString strline;
 ULONGLONG filelength = 0;
 ULONGLONG nextlinepostion = 0;
 ULONGLONG currentpostion = 0;
 LPCTSTR wordwanted = _T("END");
 ULONGLONG linelength = 0;
 ULONGLONG editpostion = 0;
 

 //文件长度
 filelength = EditFile.GetLength();             
 
 //int line;
 
 EditFile.SeekToBegin();      

 while(currentpostion != filelength)             
 {


  //获取当前文件指针偏移量
  currentpostion = EditFile.GetPosition();
  //读取一行
  EditFile.ReadString(strline);

  


  //判断是否有END,>= 0则为找到
  if(strline.Find(wordwanted) >= 0 )
  {
   //获取当前文件指针偏移量
   nextlinepostion = EditFile.GetPosition();
   //读取一行的文件长度
   linelength = (ULONGLONG)strline.GetLength();
  }
   //line = strline.GetLength();
 }

 //算出编辑层信息的偏移量
 
 return editpostion = (ULONGLONG)nextlinepostion - (ULONGLONG)linelength;
 //return editpostion = filelength - (ULONGLONG)linelength;
}

 

 

此行代码的问题在于红色部分的取值不一定,若文件结尾 与 "END"在一行,则正确

若文件结尾与"END"不在一行,则会多出之间换行符与回车符2个字符的大小。

 

换行符与回车符2个字符:此是根据 正则表达式匹配多行时 需要 “/r/n” 两个符号才能正确辨别行 (/s可以包含/r)

 

boost::tregex reg(__T("//w{5}//s+//w{4}://s+(//w+)//r//n"
        "//w{8}://s(//w+//s?//w+)//s//n"
        "//w{7}//s+//w{5}://s+//w+//s//n"
        "//w{6}://s+//((-?//d+//.//d+),//s(-?//d+//.//d+)//)//s+-//s+"
        "//((-?//d+//.//d+),//s(-?//d+//.//d+)//)"));

 

正确代码应为:

 

ULONGLONG CmapfileDlg::Seekeditpostion(CStdioFile &EditFile)
{
 //保存从指定位置编辑之后余下的文件内容
                 
 CString strline;
 ULONGLONG filelength = 0;
 ULONGLONG currentpostion = 0;
 LPCTSTR wordwanted = _T("END");
 ULONGLONG linelength = 0;
 ULONGLONG editpostion = 0;
 ULONGLONG temp;
 ULONGLONG temp2;

 //文件长度
 filelength = EditFile.GetLength();              

 EditFile.SeekToBegin();      

 while(currentpostion != filelength)             
 {


  //获取当前文件指针偏移量
  currentpostion = EditFile.GetPosition();
  //读取一行
  EditFile.ReadString(strline);

  //temp2 = EditFile.GetPosition();


  //判断是否有END,>= 0则为找到
  if(strline.Find(wordwanted) >= 0 )
  {
   //获取当前文件指针偏移量
   editpostion = currentpostion;

   //读取一行的文件长度
   linelength = (ULONGLONG)strline.GetLength();
  }

 }

 //算出编辑层信息的偏移量
 

 return editpostion;
}

 

 

另外:

 

CStdioFile EditFile2;

 CFileException e;

 if(CmapfileDlg::EditFileNameAll == "")    //未选定文件
 {
  MessageBox(_T("未选定编辑的文件"));
  return;
 }
 
 if(!EditFile2.Open(CmapfileDlg::EditFileNameAll,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite,&e))
 {
 #ifdef _DEBUG
  afxDump<<_T("文件未能打开")<<e.m_cause<<_T("/n");
 #endif
 }

 

 LONGLONG strlastlength;
 ULONGLONG filelength;
 CString strlast; 
 
 
 //file的长度
 filelength = EditFile2.GetLength();

 if(filelength == 0)
 {
  MessageBox(_T("指定的文件为空"));
  return;
 }

 

 //获取开始编辑的位置
 ULONGLONG editpostion = Seekeditpostion(EditFile2);


 //strlast的长度;
 strlastlength = (LONGLONG)filelength - (LONGLONG)editpostion;  
 
 EditFile2.Close();

 CFile EditFile;

 

 if(CmapfileDlg::EditFileNameAll == "")    //未选定文件
 {
  MessageBox(_T("未选定编辑的文件"));
  return;
 }
 
 if(!EditFile.Open(CmapfileDlg::EditFileNameAll,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite,&e))
 {
 #ifdef _DEBUG
  afxDump<<_T("文件未能打开")<<e.m_cause<<_T("/n");
 #endif
 }

 //文件指针移动到最后一个“END”那一行
 EditFile.Seek(editpostion,CFile::begin);        

 //读取余下的内容
 EditFile.Read(strlast.GetBuffer(strlastlength),strlastlength );   
 strlast.ReleaseBuffer(strlastlength );

 //回到最后一个“END”那行
 EditFile.Seek(editpostion,CFile::begin);

 

 

红色处又改为用CFILE读取剩下内容的原因为CStdioFile的read会导致末尾乱码的问题

主要是CStdioFile的问题。  

CStdionFile csf;
  csf.Read(m_disp.GetBuffer(csf.GetLength()),csf.GetLength());  
  这里会忽略掉   0x0D的(即回车)。  
  如果你是设为   CFile   csf;  
  if(csf.Open     ("E://test//log.txt",/*CFile::modeCreate|CFile::modeNoTruncate|*/CFile::modeReadWrite)==NULL)   //这里不要CFile::typeText  
  比较就知道了。  
  所以建议,如用CStdioFile的,就只用它的ReadString好了。  
  或者全改为CFile较稳健,一定可以读取全部的

 

 

原创粉丝点击