/******************************************************************************
* File Name : DataFile.h *
* Description : The CDataFile class is used to create and modify *
* data files such as *.ini and *.cfg. *
* Creator : Laughsky(LiQintao) *
* Create time : 2001/9/25 *
* Bug Report : laugh_sky@hotmail.com || muzilee@263.net *
******************************************************************************/
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DATAFILE_H__93A9DBB1_86C9_4A4D_8E2F_B91B5BBC6469__INCLUDED_)
#define AFX_DATAFILE_H__93A9DBB1_86C9_4A4D_8E2F_B91B5BBC6469__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
///////////////////////////////////////////////////////////////
#define FILE_MAX_LENGTH 1024*50
#define CREATE_MODE_REBUILD CFile::modeCreate
#define CREATE_MODE_NOREBUILD CFile::modeNoTruncate | CFile::modeCreate
#define OPEN_MODE_READ CFile::modeRead
#define OPEN_MODE_WRITE CFile::modeReadWrite
#define OPEN_MODE_READWRITE CFile::modeReadWrite
#define WRITE_MODE_INSERT 2000
#define WRITE_MODE_OVERWRITE 2001
#define WRITE_MODE_DELETE 2002
#define FLAG_FILE_EXIST 3000
#define FLAG_FILE_NOEXIST 3001
class CDataFile
{
public:
void DeleteFile(LPCTSTR lpszFileName);
void WriteLine(CString& wString, UINT nFlag);
BOOL MoveToLine(UINT line);
UINT GetLines();
void CloseFile();
BOOL OpenFile(LPCTSTR lpszFileName, UINT nFlags);
INT CheckFileExsist(LPCTSTR lpszFileName);
BOOL ReadLine(CString& rString);
BOOL CreateFile(LPCTSTR lpszFileName, UINT nFlags);
CDataFile();
virtual ~CDataFile();
private:
void MoveEnd();
void MoveStart();
CString FileName; // Save the specified file name
UINT moveLine; // Save the number of line at current pointer position
BOOL IsFileOpen; // If file has been opened,it is TRUE
CStdioFile file;
};
#endif // !defined(AFX_DATAFILE_H__93A9DBB1_86C9_4A4D_8E2F_B91B5BBC6469__INCLUDED_)
=========================================================================
/******************************************************************************
* File Name : DataFile.CPP *
* Description : The CDataFile class is used to create and modify *
* data files such as *.ini and *.cfg. *
* Creator : Laughsky(LiQintao) *
* Create Time : 2001/9/25 *
* Bug Report : laugh_sky@hotmail.com || muzilee@263.net *
******************************************************************************/
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DataFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDataFile::CDataFile()
{
IsFileOpen = FALSE;
moveLine = 1;
}
CDataFile::~CDataFile()
{
}
//Create specified file:
//The nFlags may be 1. CREATE_MODE_REBUILD
// 2. CREATE_MODE_NOREBUILD
BOOL CDataFile::CreateFile(LPCTSTR lpszFileName, UINT nFlags)
{
if (!OpenFile(lpszFileName, nFlags))
return FALSE;
CloseFile();
return TRUE;
}
//Read the specified line
BOOL CDataFile::ReadLine(CString &rString)
{
if (!IsFileOpen)
return FALSE;
if (!file.ReadString(rString))
return FALSE;
return TRUE;
}
// Check if the specified file exsists
INT CDataFile::CheckFileExsist(LPCTSTR lpszFileName)
{
if (!OpenFile(lpszFileName, OPEN_MODE_READ))
{
return FLAG_FILE_NOEXIST;
}
CloseFile();
return FLAG_FILE_EXIST;
}
// Open the specified file
BOOL CDataFile::OpenFile(LPCTSTR lpszFileName, UINT nFlags)
{
if (!file.Open(lpszFileName, nFlags))
return FALSE;
IsFileOpen = TRUE;
FileName = lpszFileName;
return TRUE;
}
// Close the current file
void CDataFile::CloseFile()
{
file.Close();
IsFileOpen = FALSE;
}
UINT CDataFile::GetLines()
{
if (!IsFileOpen)
return NULL;
unsigned int lines = 0;
CString temp;
MoveStart();
// 如果最后一行为空,则不计其行数
while(file.ReadString(temp))
lines ++;
return lines;
}
// Move to the start of the file
void CDataFile::MoveStart()
{
if (IsFileOpen)
file.SeekToBegin();
return;
}
// Move the end of the file
void CDataFile::MoveEnd()
{
if (IsFileOpen)
file.SeekToEnd();
return;
}
// Move the pointer to the specified line, then you can
// read、overwrite and delete the line by using ReadLine() or WriteLine().
BOOL CDataFile::MoveToLine(UINT line)
{
if (!IsFileOpen)
return FALSE;
if (line <= 0)
{
moveLine = 1;
MoveStart();
return TRUE;
}
if (line > GetLines())
{
moveLine = GetLines()+1;
MoveEnd();
return TRUE;
}
CString temp;
MoveStart();
for (unsigned int curLine = 1; curLine < line; curLine++)
file.ReadString(temp);
DWORD pos = file.GetPosition();
file.Seek(pos, CFile::begin);
moveLine = line;
return TRUE;
}
// Write the content you specified at current line.
// The nFlag maybe 1. WRITE_MODE_INSERT
// 2. WRITE_MODE_OVERWRITE
// 3. WRITE_MODE_DELETE
void CDataFile::WriteLine(CString &wString, UINT nFlag)
{
UINT setLine = moveLine;
UINT fileLen = file.GetLength();
if (!IsFileOpen)
return ;
CString temp;
CString sTest;
sTest.Empty();
MoveToLine(setLine);
UINT upLen = file.GetPosition();
int restLen = fileLen - upLen;
if (restLen > FILE_MAX_LENGTH)
return;
CString sRestFile,sLine;
char pbuf[FILE_MAX_LENGTH];
memset(pbuf, 0, FILE_MAX_LENGTH);
switch(nFlag)
{
case WRITE_MODE_INSERT:
if (setLine <= GetLines() || GetLines() == 0)
{
MoveToLine(setLine);
file.Read(pbuf, restLen);
temp = wString+"n"+pbuf;
MoveToLine(setLine);
file.WriteString(temp);
}
else{
CString temp2;
MoveToLine(GetLines());
file.ReadString(temp2);
temp = temp2+"n"+wString;
MoveToLine(GetLines());
file.WriteString(temp);
}
break;
case WRITE_MODE_OVERWRITE:
if (setLine < GetLines())
{
MoveToLine(setLine);
ReadLine(sTest);
MoveToLine(setLine+1);
}
else
{
setLine = GetLines();
MoveToLine(GetLines());
ReadLine(sTest);
upLen = file.GetPosition(); // 如果指定覆盖的行数大于总行数,则覆盖最后一行
MoveEnd();
}
file.Read(pbuf, restLen);
if (setLine == GetLines())
temp = wString;
else
temp = wString+"n"+pbuf;
// 可能是因为CString计算长度时没有把"n"算进去,所以我们要在后面补上它的长度
fileLen = fileLen + wString.GetLength() - sTest.GetLength();
if (setLine < GetLines())
MoveToLine(setLine);
else
MoveToLine(GetLines());
file.WriteString(temp);
file.SetLength(fileLen);
break;
case WRITE_MODE_DELETE:
if (fileLen == 0)
break;
if (setLine < GetLines())
{
MoveToLine(setLine);
ReadLine(sTest);
MoveToLine(setLine+1);
}
else
{
setLine = GetLines();
MoveToLine(setLine);
upLen = file.GetPosition();
ReadLine(sTest);
MoveEnd();
}
file.Read(pbuf, restLen);
temp = pbuf;
// 可能是因为CString计算长度时没有把"n"算进去,所以我们要在后面补上它的长度
if (setLine < GetLines())
fileLen = fileLen - sTest.GetLength() -2;
else
if (GetLines() == 1)
fileLen = 0;
else
fileLen = upLen-2;// 删除上一行的\0x0D\0x0A
MoveToLine(setLine);
file.WriteString(temp);
file.SetLength(fileLen);
break;
}
}
// Delete the specified file.
void CDataFile::DeleteFile(LPCTSTR lpszFileName)
{
file.Remove(lpszFileName);
}