www.pudn.com > FileMemView.rar > FMemView.cpp
// FMemView.cpp : Implementation of CFMemView
#include "stdafx.h"
#include "FileMemView.h"
#include "FMemView.h"
/////////////////////////////////////////////////////////////////////////////
// CFMemView
STDMETHODIMP CFMemView::CreateMap(BSTR fileName, long bflag, VARIANT_BOOL *pval)
{
_bstr_t b = fileName;
char *strPathname = b;
m_bShare = 1;//bflag;
// 获取文件句柄,并设置打开模式
m_hFile = ::CreateFile(strPathname, GENERIC_WRITE|GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(!m_hFile)
{
*pval = FALSE;
return S_FALSE;
}
// 获取文件的尺寸
DWORD nFsize = ::GetFileSize(m_hFile, NULL);
// 创建文件映射对象,并设置文件映射的模式为读写,根据文件的尺寸设置映射内存的大小
if(nFsize>0)
m_hMap = ::CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
else
m_hMap = ::CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, 1024*64, NULL);
DWORD dwErr = ::GetLastError();
if(!m_hMap ) {
*pval = FALSE;
return S_FALSE;
}
// 映射整个文件,注意FILE_MAP_WRITE为读写模式
m_lpvFile = ::MapViewOfFile(m_hMap, m_bShare?FILE_MAP_WRITE:FILE_MAP_READ, 0, 0, 0);
m_pData = (byte*)m_lpvFile;
GetSize();//为m_nFsize赋初值
*pval = TRUE;
return S_OK;
}
STDMETHODIMP CFMemView::DetachMapFile()
{
if(!m_hFile) return S_FALSE;
// 关闭内存映射
::UnmapViewOfFile(m_lpvFile);
// 关闭内存映射对象和文件
::CloseHandle(m_hMap);
::CloseHandle(m_hFile);
m_hFile = NULL;
m_lpvFile = NULL;
m_hMap = NULL;
return S_OK;
}
STDMETHODIMP CFMemView::GetFileSize(long *nSize)
{
if(!m_hFile) return S_FALSE;
GetSize();
*nSize = m_nFsize;
return S_OK;
}
STDMETHODIMP CFMemView::WriteLine(unsigned char *pAarry)
{
if(!m_hFile||!m_lpvFile)
return S_FALSE;
DWORD dFsize = GetSize();
assert(m_nFsize==(dFsize-2*sizeof(DWORD)));
m_pData=(byte*)m_lpvFile + dFsize;
unsigned char* pData = (unsigned char*)m_pData;
while (*pAarry!='\0')
{
*(pData++)=*(pAarry++);
m_nFsize++;
}
*(pData++)='\r';
*(pData++)='\n';
*pData = '\0';
m_nFsize++;
m_nFsize++;
SetSize(m_nFsize);
//m_pData = (byte*)pData;
return S_OK;
}
STDMETHODIMP CFMemView::ReadLine(unsigned char *pAarry)
{
GetSize();
if(!m_hFile||!m_lpvFile||!m_nFsize)
return S_FALSE;
DWORD dOffset = GetOffset();
assert(m_dOffset==(dOffset-2*sizeof(DWORD)));
if(m_dOffset>=m_nFsize)
return S_FALSE;
if(m_nFsize==0)
{
m_dOffset=0;
return S_FALSE;
}
m_pData=(byte*)m_lpvFile + dOffset;
unsigned char* pData = (unsigned char*)m_pData;
while ((*pData!='\n')&&(*pData!='\0'))
{
*(pAarry++)=*(pData++);
m_dOffset++;
}
*(--pAarry)='\0';
if(*pData=='\n')
{
pData++;
m_dOffset++;
}
SetOffset(m_dOffset);
//m_pData = (byte*)pData;
return S_OK;
}
DWORD CFMemView::GetSize()
{
assert(m_lpvFile);
DWORD* pData = (DWORD*)m_lpvFile;
m_nFsize = *pData;
return m_nFsize+2*sizeof(DWORD);//前两个DWORD位是记录位,第一个DWORD位记录了文件的大小,第
//二个DWORD位记录了文件的偏移量
}
DWORD CFMemView::GetOffset()
{
assert(m_lpvFile);
DWORD* pData = (DWORD*)m_lpvFile+1;
m_dOffset = *pData;
return m_dOffset+2*sizeof(DWORD);//前两个DWORD位是记录位,第一个DWORD位记录了文件的大小,第
//二个DWORD位记录了文件的偏移量
}
void CFMemView::SetSize(DWORD nsize)
{
assert(m_lpvFile);
DWORD* pData = (DWORD*)m_lpvFile;
*pData = nsize;
m_nFsize = nsize;
}
void CFMemView::SetOffset(DWORD nOffSize)
{
assert(m_lpvFile);
DWORD* pData = (DWORD*)m_lpvFile+1;
*pData = nOffSize;
m_dOffset = nOffSize;
}
/////////将最后一行删除
STDMETHODIMP CFMemView::RemoveLine()
{
assert(m_lpvFile);
if(!m_lpvFile)
return S_FALSE;
DWORD dFsize = GetSize();
assert(m_nFsize==(dFsize-2*sizeof(DWORD)));
if(m_nFsize==0)
return S_FALSE;
// assert(m_nFsize>0);
m_pData=(byte*)m_lpvFile + dFsize;
unsigned char* pData = (unsigned char*)m_pData;
pData--;
m_nFsize--;
*(pData--) = '\0';
m_nFsize--;
while (1)
{
if(*pData=='\n'||m_nFsize==0)
break;
*(pData--)='\0';
m_nFsize--;
}
if(*pData=='\n')
{
*(pData+1) = '\0';
m_nFsize++;
SetSize(m_nFsize);
if(m_dOffset>m_nFsize)
{
m_dOffset=m_nFsize;
SetOffset(m_dOffset);
}
}
if(m_nFsize==0)
{
*pData = '\0';
SetSize(m_nFsize);
SetOffset(m_nFsize);
}
return S_OK;
}
STDMETHODIMP CFMemView::RemoveLineAt(long row)
{
assert(m_lpvFile);
if(!m_lpvFile)
return S_FALSE;
DWORD dFsize = GetSize();
assert(m_nFsize==(dFsize-2*sizeof(DWORD)));
if(m_nFsize==0)
return S_FALSE;
long sPos = FindPosofRow(row);
if(sPos==-1)//越界
return S_FALSE;
unsigned char* pData = (unsigned char*)m_lpvFile + 2*sizeof(DWORD) + sPos,* Dest=pData;
long ePos = sPos;
while(*(pData++)!='\n')
ePos++;
ePos++;
// unsigned char* Dest = (unsigned char*)m_lpvFile + 2*sizeof(DWORD)+sPos;
unsigned char* Scr = (unsigned char*)m_lpvFile + 2*sizeof(DWORD)+ePos;
for(DWORD s = sPos;s<=m_nFsize;s++)
*(Dest++)=*(Scr++);
SetSize(m_nFsize-ePos+sPos);
if(m_dOffset>sPos)
SetOffset(m_dOffset-ePos+sPos);
return S_OK;
}
STDMETHODIMP CFMemView::Read(byte *pAarry, long nSize)
{
if(!m_hFile||!m_lpvFile)
return S_FALSE;
assert((DWORD)nSize<=m_nFsize);
memcpy(pAarry,(byte*)m_lpvFile + 2*sizeof(DWORD),nSize);
return S_OK;
}
STDMETHODIMP CFMemView::Write(byte *pAarry, long nSize)
{
if(!m_hFile)
return S_FALSE;
if(m_lpvFile)
::UnmapViewOfFile(m_lpvFile);
m_lpvFile = NULL;
if(m_hMap)
::CloseHandle(m_hMap);
m_hMap = NULL;
m_hMap = ::CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, nSize, NULL);
if(!m_hMap)
return S_FALSE;
// 映射整个文件,FILE_MAP_WRITE为读写模式
m_lpvFile = ::MapViewOfFile(m_hMap, m_bShare?FILE_MAP_WRITE:FILE_MAP_READ, 0, 0, 0);
if(!m_lpvFile)
return S_FALSE;
memcpy((byte*)m_lpvFile + 2*sizeof(DWORD),pAarry,nSize);
DWORD *pData = (DWORD*)m_lpvFile;
*pData = nSize;
*(pData) = 0;
return S_OK;
}
STDMETHODIMP CFMemView::Save()
{
if(!m_lpvFile)
return S_FALSE;
FlushViewOfFile(m_lpvFile,0);
return S_OK;
}
///寻找到一行的头地址,以0为基准
long CFMemView::FindPosofRow(long row)
{
assert(m_lpvFile!=NULL);
long pos=0,r=0;
unsigned char* pData = (unsigned char*)m_lpvFile+2*sizeof(DWORD);//数据记录从两个信息DWORD位以后开始
while(r=m_nFsize)
return -1;
}
return pos;
}
/*
STDMETHODIMP CFMemView::GetBuffer(unsigned char **pData)
{
// TODO: Add your implementation code here
DWORD dFsize = GetSize();
assert(m_nFsize==(dFsize-2*sizeof(DWORD)));
assert(m_nFsize>0);
if(!(m_nFsize>0))
return S_FALSE;
*pData = new unsigned char[m_nFsize];
memcpy(*pData,(unsigned char*)m_lpvFile+2*sizeof(DWORD),m_nFsize);
return S_OK;
}*/