// 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_)
//
//////////////////////////////////////////////////////////////////////#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_)
//
//////////////////////////////////////////////////////////////////////#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;
}
}
定义文件头
struct MyFileHead
{
char szFileMark[3]; }
定义文件头
struct MyFileHead
{
char szFileMark[3];
DWORD others....
}
struct MyOneRecordData
{
char szName[20];
int nAge;
...
}
然后这样构造
CBBRecordFile(sizeof(MyFileHead),sizeof(MyOneRecordData));