// BBRecordFile.h: interface for the CBBRecordFile class.
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_BBRECORDFILE_H__0934D6F3_9B42_43F3_A079_5E1BC24351AD__INCLUDED_)
#define AFX_BBRECORDFILE_H__0934D6F3_9B42_43F3_A079_5E1BC24351AD__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000//记录型文件操作类:
//作者:seesi
//时间:2001.4.20
//E_Mail:[email protected]
//说明:对记录型的文件进行操作的类,文件可以为文本文件或者二进制文件。
//使用:1. 定义一个操作类的实例,
// 参数构造:nHeadLen为文件头的长度,nOneRecordLen为一条记录的长度
// e.g. CBBRecordFile(12,30);
// 2.调用Open函数打开记录文件,参数与CFile类Open方法一样,请参考CFile类
// 3.然后可以用函数WriteData,ReadData,DeleteData,WriteHead,AppenData,ReadHead进行数据的增删改操作
// 4.必要的时候建议调用Close方法,以释放文件打开所占的资源,虽然本类的析构函数能自动关闭
//class CBBRecordFile  
{
public:
int ReadData(int nIndex,void* lpData);
int ReadHead(void* lpData);
int GetRecordCount();
BOOL IsOpen();//文件是否打开
BOOL DeleteData(int nIndex);//删除一条记录
BOOL WriteData(const void* data,int nIndex);//修改或者添加一条记录
BOOL WriteHead(const void* head);//写文件头部信息
BOOL AppenData(const void* data);//添加记录
void Close(); BOOL Open(LPCTSTR lpszFileName,UINT nOpenFlag=CFile::modeReadWrite,CFileException* fileException=NULL);//打开目标文件
CBBRecordFile(int nHeadLen,int nOneRecordLen);//参数构造
virtual ~CBBRecordFile();private:
CFile m_fileMain;//主文件
BOOL m_bFileOpen;//文件打开否
int m_nHeadLen;//文件头长
int m_nOneRecordLen;//一条记录的大小
int m_nFileTotalLen;//文件总长度
int m_nRecordCount;//记录的条数
CString m_strDataRead;//当前读的数据
protected:
void Write(const void* data,BOOL bHead=FALSE);//写数据,供内部调用
};
#endif // !defined(AFX_BBRECORDFILE_H__0934D6F3_9B42_43F3_A079_5E1BC24351AD__INCLUDED_)

解决方案 »

  1.   

    // BBRecordFile.cpp: implementation of the CBBRecordFile class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "BBRecordFile.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CBBRecordFile::CBBRecordFile(int nHeadLen,int nOneRecordLen)
    {
    ASSERT(nOneRecordLen);
    m_nHeadLen=nHeadLen;
    m_nOneRecordLen=nOneRecordLen;
    m_bFileOpen=FALSE;
    m_nFileTotalLen=0;//文件总长度
    m_nRecordCount=0;//记录的条数

    }CBBRecordFile::~CBBRecordFile()
    {
    Close();
    //delete m_cDataRead;
    }BOOL CBBRecordFile::Open(LPCTSTR lpszFileName, UINT nOpenFlag,CFileException* fileException)
    {
    if(m_bFileOpen)
    return TRUE;
    m_bFileOpen = m_fileMain.Open(lpszFileName,nOpenFlag,fileException);
    if (m_bFileOpen)
    {
    m_nFileTotalLen = m_fileMain.GetLength();
    }
    //检测是否符合文件格式的标准,头部信息不足
    if(m_nFileTotalLen!=0 && m_nFileTotalLen < m_nHeadLen)
    {
    this->Close();//不符合标准
    #if _DEBUG
    AfxMessageBox(_T("错误:可能文件格式有误!"));
    #endif
    m_bFileOpen=FALSE;
    }
    //记录信息不足
    if(m_nFileTotalLen>m_nHeadLen && ((m_nFileTotalLen - m_nHeadLen)%m_nOneRecordLen!=0))
    {
    this->Close();//不符合标准;
    #if _DEBUG
    AfxMessageBox(_T("错误:可能文件格式有误!"));
    #endif
    m_bFileOpen=FALSE;
    } m_nRecordCount = (m_nFileTotalLen - m_nHeadLen) /m_nOneRecordLen;
    return m_bFileOpen;
    }void CBBRecordFile::Close()
    {
    if(m_bFileOpen)
    {
    m_fileMain.Close();
    m_bFileOpen=FALSE;
    }
    }//DEL BYTE* CBBRecordFile::ReadData(int nIndex)
    //DEL {
    //DEL 
    //DEL }//添加记录
    BOOL CBBRecordFile::AppenData(const void *data)
    {
    ASSERT(sizeof(data)!=m_nOneRecordLen);
    if(!m_bFileOpen)
    return FALSE;
    m_fileMain.SeekToEnd();
    Write(data);
    m_nRecordCount++;
    m_nFileTotalLen+=m_nOneRecordLen;
    return TRUE;
    }//写头
    BOOL CBBRecordFile::WriteHead(const void *head)
    {
    ASSERT(sizeof(head)!=m_nHeadLen);
    if(!m_bFileOpen)
    return FALSE;
    m_fileMain.SeekToBegin();
    Write(head,TRUE);
    return TRUE;
    }void CBBRecordFile::Write(const void* data,BOOL bHead)
    {
    if(!m_bFileOpen)
    return;
    if(bHead)
    {
    m_fileMain.Write(data,m_nHeadLen);
    m_fileMain.Flush();
    }
    else
    {
    m_fileMain.Write(data,m_nOneRecordLen);
    m_fileMain.Flush();
    }
    }
    //写或者修改数据,在任何位置,如果指定的记录索引超出最大索引,将在文件后添加记录
    BOOL CBBRecordFile::WriteData(const void *data, int nIndex)
    {
    if(!m_bFileOpen)
    return FALSE;
    if(nIndex<0)
    {
    nIndex = 0;
    }
    int nCurPos =  m_nHeadLen + nIndex * m_nOneRecordLen;
    if(nCurPos>m_nFileTotalLen)
    {
    AppenData(data);
    }
    else
    {
    m_fileMain.Seek(nCurPos,CFile::begin);
    Write(data);
    }
    return TRUE;
    }//删除一条数据记录,参数为索引,如果索引超出范围,则删除任何记录
    BOOL CBBRecordFile::DeleteData(int nIndex)
    {

    if(!m_bFileOpen)
    return FALSE; if(nIndex > m_nRecordCount)
    return FALSE; CFile fileTemp;
    CString strTempFileName;

    strTempFileName = "~~001.tmp";
    if(!(fileTemp.Open(strTempFileName,CFile::modeCreate|CFile::modeReadWrite,NULL)))
    return FALSE; BYTE buff[1024];
    memset(buff,0,1024);

    DWORD dwDelPos = m_nHeadLen + m_nOneRecordLen * nIndex;
    DWORD dwReadedLen;
    dwReadedLen=0;
    DWORD dwReadReal=1024; if(dwDelPos < 1024)
    {
    dwReadReal = dwDelPos;
    }
    //先读头
    int sz=0;
    m_fileMain.SeekToBegin();
    while((sz=m_fileMain.Read(&buff,dwReadReal))>0 && dwDelPos > dwReadedLen )
    {
    fileTemp.Write(buff,sz);
    fileTemp.Flush();
    dwReadedLen += sz;
    } //读后面的数据
    sz=0;
    m_fileMain.Seek(m_nOneRecordLen + dwDelPos ,CFile::begin);
    fileTemp.SeekToEnd();
    while((sz=m_fileMain.Read(&buff,1024))>0)
    {
    fileTemp.Write(buff,sz);
    fileTemp.Flush();
    }

    //覆盖当前文件
    m_fileMain.SeekToBegin();
    fileTemp.SeekToBegin();
    while((sz=fileTemp.Read(&buff,1024))>0)
    {
    m_fileMain.Write(buff,sz);
    }
    fileTemp.Close(); //重新设置大小
    m_fileMain.SetLength(m_nFileTotalLen - m_nOneRecordLen); CFile::Remove(strTempFileName); // reload
    m_fileMain.Flush(); m_nRecordCount--;
    m_nFileTotalLen-=m_nOneRecordLen; return TRUE;
    }BOOL CBBRecordFile::IsOpen()
    {
    return m_bFileOpen;
    }
    int CBBRecordFile::GetRecordCount()
    {
    return m_nRecordCount;
    }
    int CBBRecordFile::ReadHead(void *lpData)
    {
    if(!m_bFileOpen)
      return -1;   m_fileMain.SeekToBegin();
      if(m_fileMain.Read(lpData,m_nHeadLen)>0)
    {
    return 0;
    }
    else
    {
    return -1;
    }
    }int CBBRecordFile::ReadData(int nIndex, void *lpData)
    {
    if(!m_bFileOpen)
    return -1;
    ASSERT(nIndex<m_nRecordCount);
    int nCurReadPos;
    if(nIndex<0)
    {
    nIndex=0;
    }
    else
    {
    }
    nCurReadPos= m_nHeadLen + nIndex * m_nOneRecordLen;
    m_fileMain.Seek(nCurReadPos,CFile::begin);
    if(m_fileMain.Read(lpData,m_nOneRecordLen)>0)
    {
    return 0;
    }
    else
    {
    return -1;
    }
    }
      

  2.   

    兄弟,你的给我解除恶劣影响啊!否则~~嘿嘿~~代码里有bug的,不给你纠正了
      

  3.   

    构造的时候应该这样
    定义文件头
    struct MyFileHead
    {
      char szFileMark[3]; }
      

  4.   

    构造的时候应该这样
    定义文件头
    struct MyFileHead
    {
      char szFileMark[3];
      DWORD others....   

    struct MyOneRecordData
    {
      char szName[20];
      int  nAge;
      ...
    }
    然后这样构造
    CBBRecordFile(sizeof(MyFileHead),sizeof(MyOneRecordData));