writefile

场景:关于ReadFile跟WriteFile

关于ReadFile和WriteFile
我先用WriteFile写入数据,再重新打开程序读取数据发现只读取了部分数据?
CtestDlg::OnInitDialog()代码:

CString str1,strPath;
WCHAR lpBuffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH,lpBuffer);
strPath.Format(_T("%s"),lpBuffer);
AfxMessageBox(strPath);
str1+=strPath+_T("\\avaliable.db");

hFileAble=CreateFile(str1,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,
OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hFileAble)
{
strPath.Format(_T("创建文件失败:%d"),GetLastError());
AfxMessageBox(strPath);
return FALSE;
}

写入数据代码:
	
        DWORD dwWritten;
CCar tempClass1;
tempClass1.m_dMiles=1111;
tempClass1.m_strID=_T("新年快乐");
tempClass1.m_dTraveled=0;
tempClass1.m_strRentDate=_T("1");
tempClass1.m_strRTNDate=_T("1");
tempClass1.next=NULL;
WriteFile(hFileAble,&tempClass1,sizeof(CCar),&dwWritten,NULL);
WriteFile(hFileAble,&tempClass1,sizeof(CCar),&dwWritten,NULL);
WriteFile(hFileAble,&tempClass1,sizeof(CCar),&dwWritten,NULL);
FlushFileBuffers(hFileAble);

DWORD dwRead;
Sleep(100);
CString str1;
CCar tempClass2,tempClass3,*tempClass4;
tempClass4=new CCar();
SetFilePointer(hFileAble,0,0,FILE_BEGIN);
ReadFile(hFileAble,&tempClass2,sizeof(CCar),&dwRead,NULL);
ReadFile(hFileAble,&tempClass3,sizeof(CCar),&dwRead,NULL);
ReadFile(hFileAble,tempClass4,sizeof(CCar),&dwRead,NULL);

str1.Format(_T("LastError:%d"),GetLastError());
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass2.m_dMiles,tempClass2.m_strID);
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass3.m_dMiles,tempClass3.m_strID);
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass4->m_dMiles,tempClass4->m_strID);
MessageBox(str1);
CloseHandle(hFileAble);

读取数据代码:
	DWORD dwRead;
Sleep(100);
CString str1;
CCar tempClass2,tempClass3,*tempClass4;
tempClass4=new CCar();
SetFilePointer(hFileAble,0,0,FILE_BEGIN);
ReadFile(hFileAble,&tempClass2,sizeof(CCar),&dwRead,NULL);
ReadFile(hFileAble,&tempClass3,sizeof(CCar),&dwRead,NULL);
ReadFile(hFileAble,tempClass4,sizeof(CCar),&dwRead,NULL);

str1.Format(_T("LastError:%d"),GetLastError());
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass2.m_dMiles,tempClass2.m_strID);
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass3.m_dMiles,tempClass3.m_strID);
MessageBox(str1);
str1.Format(_T("%f\n%s"),tempClass4->m_dMiles,tempClass4->m_strID);
MessageBox(str1);
CloseHandle(hFileAble);

CCar类如下:
class CCar
{
public:
CCar(void);
~CCar(void);
public:
CString m_strID;
double m_dMiles;
double m_dTraveled;
CString m_strRTNDate;
CString m_strRentDate;
CCar   *next;
};

//还有个错误在执行完相应全部代码段后就是:test.exe 中的 0x5cd37321 (mfc90ud.dll) 处未处理的异常: 0xC0000005: 读取位置 0xfeeefeee 时发生访问冲突
file c mfc

------解决方案--------------------
剩下的就是cstring了,不能直接文件io,因为cstring的字符串部分实际是动态分配的,cstring类中只存了个指针
------解决方案--------------------
CString的文件存储只能自己实现
写文件时可以先保存字符串长度,再保存字符串文本
读文件时先读出字符串长度,new一块数组,再按长度读字符串文本到数组,然后再赋值到Cstring

或者就直接用MFC的序列化
------解决方案--------------------
其实你那个car 不用CStriong 用 TCHAR (如【10】)更好
------解决方案--------------------
用序列化的方式,有很多现成的可以使用


class CCar
{
public:
  CCar(void) : m_dMiles(0), m_dTraveled(0), next(NULL)
  {    
  }

  virtual ~CCar(void)
  {
    if(next)
    {
      delete next;
      next = NULL;
    }
  }

public:
  CString m_strID;
  double m_dMiles;
  double m_dTraveled;
  CString m_strRTNDate;
  CString m_strRentDate;
  CCar   *next;

public:
  virtual BOOL operator == (CCar &Ob)
  {
    if(m_strID == Ob.m_strID
      && m_dMiles == Ob.m_dMiles
      && m_dTraveled == Ob.m_dTraveled
      && m_strRTNDate == Ob.m_strRTNDate
      && m_strRentDate == Ob.m_strRentDate)
    {
      if((next==NULL && Ob.next == NULL) 
------解决方案--------------------
 (*next == *Ob.next))
        return TRUE;
    }
    return FALSE;
  }

  friend CArchive& operator << ( CArchive& ar, CCar &Ob)
  {     
    ar << Ob.m_strID;
    ar << Ob.m_dMiles;
    ar << Ob.m_dTraveled;
    ar << Ob.m_strRTNDate;
    ar << Ob.m_strRentDate;
    ar << (Ob.next ? true:false);
    if(Ob.next)
      ar << *Ob.next;
    return ar;
  }

  friend CArchive& operator >> ( CArchive& ar, CCar &Ob)
  {
    bool bWithNext;
    ar >> Ob.m_strID;
    ar >> Ob.m_dMiles;
    ar >> Ob.m_dTraveled;
    ar >> Ob.m_strRTNDate;
    ar >> Ob.m_strRentDate;
    ar >> bWithNext;
    if(bWithNext)
    {
      Ob.next = new CCar;
      ar >> *Ob.next;
    }
    return ar;
  }

};



//测试代码  
{  
  CString szFileName = _T("d:\\temp\\testCar.txt");

  CCar testCar, testCar2;
  testCar.m_strID = _T("1234");
  testCar.next = new CCar;
  testCar.next->m_strID = _T("5678");
    
  try
  {
    //store
    {
      CFile file(szFileName, CFile::modeCreate
------解决方案--------------------
CFile::modeWrite);
      CArchive ar(&file, CArchive::store);
      ar << testCar;
      ar.Close();
      file.Close();  
    }

    //load
    {
      CFile file(szFileName, CFile::modeRead);
      CArchive ar(&file, CArchive::load);
      ar >> testCar2;
      ar.Close();
      file.Close();
    }

    ASSERT(testCar2 == testCar);
  }
  catch(CFileException *e)
  {
    e->ReportError();
    e->Delete();    
  }
}