📄 kfile.cpp
字号:
// KFile.cpp: implementation of the KFile class.
//
//////////////////////////////////////////////////////////////////////
#include "..\stdafx.h"
#include "KFile.h"
PDWORD KFile::m_pUsedBitmap=NULL;
PBYTE KFile::m_pBuffer=NULL;
int KFile::m_nBufferBlock=0;
KArray<KFile::FILE> KFile::m_arrFile;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
KFile::KFile()
{
m_nFile=-1;
}
KFile::~KFile()
{
Close();
}
DWORD KFile::Verify(BOOL bWrite)
{
DWORD i,j,nCnt;
PDWORD pData;
pData=(DWORD*)m_pBuffer;
nCnt=FILE_BLOCKBYTES/sizeof(DWORD)-1;
j=-1;
for(i=0;i<nCnt;i++)
{
j^=*pData++;
}
if(bWrite)*pData=j;
else j=(j==*pData)?TRUE:FALSE;
return j;
}
void KFile::Init()
{
int i,j,nCnt,nCnt2;
DWORD nPos;
m_pBuffer=(PBYTE)HeapAlloc(FILE_BLOCKBYTES);
m_nBufferBlock=0;
FILE_READBLOCK(m_pBuffer,m_nBufferBlock);
if(!Verify(FALSE))
{
//格式化
ZeroMemory(m_pBuffer,FILE_BLOCKBYTES);
FILE_WRITEBLOCK(m_pBuffer,m_nBufferBlock);
}
nPos=(DWORD)m_pBuffer;
//读使用位图
i=sizeof(DWORD)*8;
nCnt=FILE_BLOCKCOUNT/i;
if(FILE_BLOCKCOUNT%i)nCnt++;
m_pUsedBitmap=new DWORD[nCnt];
CopyMemory(m_pUsedBitmap,PVOID(nPos),sizeof(DWORD)*nCnt);
nPos+=sizeof(DWORD)*nCnt;
//读取文件列表
nCnt=*PDWORD(nPos);
nPos+=sizeof(DWORD);
m_arrFile.SetSize(nCnt,-1);
for(i=0;i<nCnt;i++)
{
FILE& f=m_arrFile[i];
f.strName=LPCTSTR(nPos);
nPos+=sizeof(TCHAR)*(f.strName.GetLength()+1);
f.nDate=*PDWORD(nPos);nPos+=sizeof(DWORD);
f.nSize=*PDWORD(nPos);nPos+=sizeof(DWORD);
nCnt2=f.nSize/FILE_BLOCKBYTES;
if(f.nSize%FILE_BLOCKBYTES)nCnt2++;
f.pBlock=new USHORT[(nCnt2&~7)+8];
j=sizeof(USHORT)*((nCnt2 & 1)?nCnt2+1:nCnt2);
CopyMemory(f.pBlock,PVOID(nPos),j);
nPos+=sizeof(USHORT)*j;
}
}
void KFile::Unload()
{
int i,j,nCnt,nCnt2;
DWORD nPos;
PDWORD pOld,pNew;
if(m_nBufferBlock<0)
{
FILE_WRITEBLOCK(m_pBuffer,-m_nBufferBlock);
}
nPos=(DWORD)m_pBuffer;
//写使用位图
i=sizeof(DWORD)*8;
nCnt=FILE_BLOCKCOUNT/i;
if(FILE_BLOCKCOUNT%i)nCnt++;
CopyMemory(PVOID(nPos),m_pUsedBitmap,sizeof(DWORD)*nCnt);
nPos+=sizeof(DWORD)*nCnt;
delete[] m_pUsedBitmap;
//写文件列表
*PDWORD(nPos)=nCnt=m_arrFile.GetSize();
nPos+=sizeof(DWORD);
for(i=0;i<nCnt;i++)
{
FILE& f=m_arrFile[i];
j=sizeof(TCHAR)*(f.strName.GetLength()+1);
CopyMemory(PVOID(nPos),f.strName,j);
nPos+=j;
*PDWORD(nPos)=f.nDate;nPos+=sizeof(DWORD);
*PDWORD(nPos)=f.nSize;nPos+=sizeof(DWORD);
nCnt2=f.nSize/FILE_BLOCKBYTES;
if(f.nSize%FILE_BLOCKBYTES)nCnt2++;
j=sizeof(USHORT)*((nCnt2 & 1)?nCnt2+1:nCnt2);
CopyMemory(PVOID(nPos),f.pBlock,j);
nPos+=sizeof(USHORT)*j;
delete[] f.pBlock;
}
m_arrFile.SetSize(0,-1);
m_nBufferBlock=0;
Verify(TRUE);
pNew=(PDWORD)m_pBuffer;
pOld=(PDWORD)HeapAlloc(FILE_BLOCKBYTES);
FILE_READBLOCK(pOld,m_nBufferBlock);
nCnt=FILE_BLOCKBYTES/sizeof(DWORD);
for(i=0;i<nCnt;i++)
{
if(pNew[i]!=pOld[i])
{
FILE_WRITEBLOCK(m_pBuffer,m_nBufferBlock);
break;
}
}
HeapFree(pOld);
HeapFree(m_pBuffer);
}
int KFile::GetFileIndex(LPCTSTR szFile)
{
int i,j;
for(i=m_arrFile.GetSize()-1;i>=0;i--)
{
j=m_arrFile[i].strName.GetLength()+1;
if(m_arrFile[i].strName.Compare(szFile,-j)==0)
{
break;
}
}
return i;
}
LPCTSTR KFile::FindFirst()
{
if(m_arrFile.GetSize()<1)return NULL;
Close();
m_nFile=0;
m_nPostion=0;
return m_arrFile[0].strName;
}
LPCTSTR KFile::FindNext()
{
if(m_nFile>-1)
{
if(m_nFile<m_arrFile.GetSize()-1)
{
int i=m_nFile;
Close();
m_nFile=i+1;
m_nPostion=0;
}
else m_nFile=-1;
}
return m_nFile>-1?LPCTSTR(m_arrFile[m_nFile].strName):NULL;
}
BOOL KFile::Delete()
{
int i=m_nFile;
SetLength(0);
Close();
delete[] m_arrFile[i].pBlock;
m_arrFile.RemoveAt(i);
return TRUE;
}
BOOL KFile::MoveTo(LPCTSTR szNewName)
{
int i=GetFileIndex(szNewName);
if(i<0)
{
m_arrFile[m_nFile].strName=szNewName;
}
return i>-1;
}
BOOL KFile::CopyTo(LPCTSTR szNewName,BOOL bOverWrite)
{
int i=GetFileIndex(szNewName);
if(i<0)
{
FILE f;
f.strName=szNewName;
f.nSize=0;
f.nDate=0;
f.pBlock=new USHORT[8];
i=m_arrFile.Add(f);
}
else if(bOverWrite)
{
m_arrFile[i].strName=szNewName;
}
else i=-1;
if(i>-1)
{
int nBlock,nOffset,nBytes;
int nCount=m_nFile,nPos=0;
m_nFile=i;
SetLength(m_arrFile[nCount].nSize);
m_nFile=nCount;
if(m_nBufferBlock<0)
{
FILE_WRITEBLOCK(m_pBuffer,-m_nBufferBlock);
}
nCount=m_arrFile[m_nFile].nSize;
while(nCount>0)
{
nBlock=nPos/FILE_BLOCKBYTES;
nOffset=nPos%FILE_BLOCKBYTES;
nBytes=FILE_BLOCKBYTES-nOffset;
m_nBufferBlock=m_arrFile[m_nFile].pBlock[nBlock];
FILE_READBLOCK(m_pBuffer,m_nBufferBlock);
FILE_WRITEBLOCK(m_pBuffer,m_arrFile[i].pBlock[nBlock]);
nCount-=nBytes;
nPos+=nBytes;
}
}
return i>-1;
}
BOOL KFile::Open(LPCTSTR szFile,int nFlags)
{
m_nFile=GetFileIndex(szFile);
if(m_nFile==-1 && (nFlags & modeCreate))
{
FILE f;
f.strName=szFile;
f.nSize=0;
f.nDate=0;
f.pBlock=new USHORT[8];
m_nFile=m_arrFile.Add(f);
}
m_nPostion=0;
return m_nFile>-1;
}
void KFile::Close()
{
m_nFile=-1;
}
void KFile::ReadWriteBuffer(PBYTE& pBuf, int& nCount)
{
int nBlock,nOffset,nBytes;
nBlock=nCount;
nBlock=ABS(nBlock);
nOffset=m_nPostion%FILE_BLOCKBYTES;
nBytes=FILE_BLOCKBYTES-nOffset;
nBytes=min(nBytes,nBlock);
nBlock=m_nPostion/FILE_BLOCKBYTES;
nBlock=m_arrFile[m_nFile].pBlock[nBlock];
if(ABS(m_nBufferBlock)!=nBlock)
{
if(m_nBufferBlock<0)
{
FILE_WRITEBLOCK(m_pBuffer,-m_nBufferBlock);
}
m_nBufferBlock=nBlock;
FILE_READBLOCK(m_pBuffer,m_nBufferBlock);
}
if(nCount>0) //读
{
CopyMemory(pBuf,m_pBuffer+nOffset,nBytes);
nCount-=nBytes;
}
else if(nCount<0) //写
{
CopyMemory(m_pBuffer+nOffset,pBuf,nBytes);
m_nBufferBlock=-nBlock;
nCount+=nBytes;
}
pBuf+=nBytes;
m_nPostion+=nBytes;
}
int KFile::Write(LPCVOID pBuf, int nCount)
{
int nBytes;
PBYTE pData=PBYTE(pBuf);
nBytes=m_nPostion+nCount;
if(nBytes>m_arrFile[m_nFile].nSize)SetLength(nBytes);
nBytes=nCount;
nCount=-nCount;
while(nCount<0)
{
ReadWriteBuffer(pData,nCount);
}
return nBytes;
}
int KFile::Read(PVOID pBuf, int nCount)
{
int nBytes;
PBYTE pData=PBYTE(pBuf);
nBytes=m_arrFile[m_nFile].nSize-m_nPostion;
nBytes=nCount=min(nBytes,nCount);
while(nCount>0)
{
ReadWriteBuffer(pData,nCount);
}
return nBytes;
}
void KFile::WriteString(LPCTSTR lpsz)
{
LPCTSTR s=lpsz;
while(*s)
{
switch(*s)
{
case '\r':
if(*(s+1)=='\n')break;
case '\n':
Write(lpsz,s-lpsz);
Write("\r\n",2);
lpsz=s+1;
break;
}
s++;
}
Write(lpsz,s-lpsz);
Write("\r\n",2);
}
int KFile::ReadString(LPTSTR lpsz, int nMax)
{
int nCount;
PBYTE pStart,pData=PBYTE(lpsz);
nMax--;
nCount=m_arrFile[m_nFile].nSize-m_nPostion;
nCount=min(nMax,nCount);
if(nCount==0)return 0;
do
{
pStart=pData;
ReadWriteBuffer(pData,nCount);
nMax=pData-pStart;
while(pStart<pData)
{
switch(*pStart)
{
case '\r':
case '\n':
case '\0':
m_nPostion-=pData-pStart-1;
pData=pStart;
nMax=0;
break;
}
if(!nMax)break;
pStart++;
}
if(!nMax)break;
}while(nCount>0);
if(nMax)
{
nCount=1;ReadWriteBuffer(pData,nCount);
if(!nCount)
{
pData--;
if(*pData!='\r')m_nPostion-=1;
}
}
if(*pData=='\r')
{
nCount=1;ReadWriteBuffer(pData,nCount);
if(!nCount)
{
pData--;
if(*pData!='\n')m_nPostion-=1;
}
}
*pData=0;
return LPTSTR(pData)-lpsz;
}
int KFile::ReadString(KString &String)
{
int nBuf,nLen;
LPTSTR pData;
nBuf=String.GetLength();
nBuf=max(64,nBuf);
pData=String.GetBuffer(nBuf);
nLen=ReadString(pData,nBuf+1);
if(nLen==nBuf)
{
for(;;)
{
String.ReleaseBuffer(nBuf);
pData=String.GetBuffer(nBuf<<1)+nBuf;
nLen=ReadString(pData,nBuf+1);
if(nLen!=nBuf)break;
nBuf<<=1;
}
nLen+=nBuf;
}
String.ReleaseBuffer(nLen);
return nLen;
}
int KFile::Seek(int nOffset, int nFrom)
{
switch(nFrom)
{
case end:
nOffset=m_arrFile[m_nFile].nSize-nOffset;
break;
case current:
nOffset+=m_nPostion;
break;
}
if(nOffset<=m_arrFile[m_nFile].nSize)m_nPostion=nOffset;
else nOffset=-1;
return nOffset;
}
int KFile::SetLength(int nNewLength)
{
int i,j,nCnt,nNewCnt,nBits;
//调整索引数组的大小
nCnt=m_arrFile[m_nFile].nSize/FILE_BLOCKBYTES;
if(m_arrFile[m_nFile].nSize%FILE_BLOCKBYTES)nCnt++;
nNewCnt=nNewLength/FILE_BLOCKBYTES;
if(nNewLength%FILE_BLOCKBYTES)nNewCnt++;
if((nCnt&~7)+8 < (nNewCnt&~7)+8)
{
PUSHORT pBlock=m_arrFile[m_nFile].pBlock;
m_arrFile[m_nFile].pBlock=new USHORT[(nNewCnt&~7)+8];
CopyMemory(m_arrFile[m_nFile].pBlock,pBlock,nCnt*sizeof(USHORT));
delete[] pBlock;
}
nBits=sizeof(DWORD)*8;
if(nNewCnt>nCnt)
{
//分配块
j=1;
for(i=nCnt;i<nNewCnt;i++)
{
while(j<FILE_BLOCKCOUNT)
{
if(!(m_pUsedBitmap[j/nBits] & (1<<(j%nBits))))
{
m_pUsedBitmap[j/nBits] |= (1<<(j%nBits));
m_arrFile[m_nFile].pBlock[i]=j;
break;
}
j++;
}
}
}
else if(nNewCnt<nCnt)
{
//释放块
for(i=nNewCnt;i<nCnt;i++)
{
j=m_arrFile[m_nFile].pBlock[i];
m_pUsedBitmap[j/nBits] &= ~(1<<(j%nBits));
}
}
m_arrFile[m_nFile].nSize=nNewLength;
return nNewLength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -