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; 
}*/