file

Published

CSPFile file; 读文本数据

CTSKFile file;读二进制数据

CFile file;

CFileFind finder;

 

CSPFile file; 读文本数据

int	CSelfDB::StoreCodetable(CStockContainer& container)
{
	if (!m_bIsOK)	return 0;

	if (container.GetSize() <= 0)
		return 0;

	// 上海指数
	CSPString	sFileNameSH	= GetRootPath();
	sFileNameSH	+= self_sh_code;

	// 深圳指数
	CSPString	sFileNameSZ	= GetRootPath();
	sFileNameSZ	+= self_sz_code;
	
	CSPFile	fileSHSE, fileSZSE;
	if (!fileSHSE.Open(sFileNameSH, CSPFile::modeCreate | CSPFile::modeWrite)
		|| !fileSZSE.Open(sFileNameSZ, CSPFile::modeCreate | CSPFile::modeWrite))
	{
		return 0;
	}

	container.Lock();
	for (int i=0; i<container.GetSize(); i++)
	{
		CStockInfo & info = container.ElementAt(i);
		CSPString	str;

		str.Format("%s,%s,%d,%s,\"%s\"\r\n", info.GetStockCode(), info.GetStockNameChs(), info.GetType(),
						info.GetStockShortName(), info.GetStockNameEnu());

		if (info.IsShangHai())
		{
			fileSHSE.Write(str, str.GetLength());
		}
		if (info.IsShenZhen())
		{
			fileSZSE.Write(str, str.GetLength());
		}
	}
	container.UnLock();

	return container.GetSize();
}

 

CTSKFile file;读二进制数据

//=============================================================================
// CSelfDB
/=============================================================================
// CTSKFile

CTSKFile::CTSKFile()
{
	Close();
}

CTSKFile::~CTSKFile()
{
	Close();
}

BOOL CTSKFile::Open(LPCTSTR lpszFileName)
{
	Close();

	if (!m_file.Open(lpszFileName, CSPFile::modeReadWrite))
		return FALSE;

	if (m_file.Read(&m_header, sizeof(m_header)) != sizeof(m_header))
	{
		SP_ASSERT(FALSE);
		return FALSE;
	}

	if (m_header.m_dwMagic != CLK_FHEADER_MAGIC)
	{
		SP_ASSERT(FALSE);
		return FALSE;
	}

	return TRUE;
}

void CTSKFile::Close()
{
	if (m_file.m_hFile != (UINT)CSPFile::hFileNull)
	{
		m_header.m_time = time(NULL);
		m_file.Seek(0, CSPFile::begin);
		m_file.Write(&m_header, sizeof(m_header));
		m_file.Close();
	}

	memset(&m_header, 0, sizeof(m_header));
	memset(&m_CurIndexRecord, 0, sizeof(m_CurIndexRecord));

	m_dwPosCurIndex	= -1;
}

// 创建空的数据文件
BOOL CTSKFile::BuildEmptyFile(LPCTSTR lpszFileName,
						DWORD dwDataType,	// 数据分类说明,see CStock::DataType
						DWORD dwMarket,			// 市场,see CStock::StockMarket,如果文件包含多个市场,则=0无效
						DWORD dwIndexRecordCount,	// 索引区记录单元个数
						DWORD dwRecordPerBlock,		// 每个Block的记录数
						BOOL bRebuildIfExists)
{
	SP_ASSERT(NULL != lpszFileName && strlen(lpszFileName) > 0);
	if (NULL == lpszFileName || strlen(lpszFileName) <= 0)
		return FALSE;

	// 如果文件存在
	if (!bRebuildIfExists && 0 == access(lpszFileName,0))
		return TRUE;

	CLK_FHEADER	header;
	memset(&header, 0,sizeof(header));
	header.m_dwMagic	= CLK_FHEADER_MAGIC;
	header.m_dwVerMajor	= CLK_FHEADER_VERMAJOR;
	header.m_dwVerMinor	= CLK_FHEADER_VERMINOR;
	strcpy(header.m_szDescript, "CLKing Stock File Structure. See www.ninebulls.com for more information.");
	header.m_dwDataType	= dwDataType;
	header.m_dwMarket	= dwMarket;
	header.m_time		= time(NULL);
	
	// 索引区信息
	header.m_dwPosFirstIndex	= sizeof(header);
	header.m_dwIndexRecordSize	= sizeof(CLK_INDEXRECORD);
	header.m_dwIndexRecordCount	= dwIndexRecordCount;
	header.m_dwStockCount		= 0;

	// 数据区信息
	switch (dwDataType)
	{
	case CStock::dataReport:
		header.m_dwDataRecordSize	= sizeof(REPORT);
		break;
	case CStock::dataMinute:
		header.m_dwDataRecordSize	= sizeof(MINUTE);
		break;
	case CStock::dataK:
		header.m_dwDataRecordSize	= sizeof(KDATA);
	default:
		SP_ASSERT(FALSE);
		return FALSE;
	}
	header.m_dwRecordPerBlock	= dwRecordPerBlock;
	header.m_dwBlockSize		= sizeof(CLK_BLOCKHEADER) + header.m_dwDataRecordSize * header.m_dwRecordPerBlock;
	header.m_dwPosFirstBlock	= sizeof(CLK_FHEADER) + header.m_dwIndexRecordSize * header.m_dwIndexRecordCount;
	header.m_dwPosFirstBlankBlock	= -1;

	CSPFile	file;
	if (!file.Open(lpszFileName, CSPFile::modeCreate | CSPFile::modeReadWrite))
	{
		SP_ASSERT(FALSE);
		return FALSE;
	}
	file.Write(&header, sizeof(header));

	for (DWORD i=0; i<header.m_dwIndexRecordCount; i++)
	{
		CLK_INDEXRECORD	index;
		memset(&index, 0, sizeof(index));
		index.m_dwMagic			= CLK_INDEXRECORD_MAGIC;
		index.m_dwPosFirstBlock	= -1;
		file.Write(&index, sizeof(index));
	}
	
	file.Flush();
	return TRUE;
}

// 重新创建,如果日期不是tmNow
BOOL CTSKFile::RemoveFileIfOutoftime(LPCTSTR lpszFileName, time_t tmNow)
{
	SP_ASSERT(NULL!=lpszFileName && strlen(lpszFileName) > 0);
	if (NULL==lpszFileName || strlen(lpszFileName) <= 0)
		return FALSE;

	CTSKFile	file;
	if (file.Open(lpszFileName))
	{
		CSPTime	ft(file.m_header.m_time);
		CSPTime	tNow(tmNow);
		
		if (CLK_FHEADER_VERMAJOR == file.m_header.m_dwVerMajor 
			&& CLK_FHEADER_VERMINOR == file.m_header.m_dwVerMinor)	// 版本相同
		{
			if (ft.GetYear() == tNow.GetYear() && ft.GetMonth() == tNow.GetMonth() && ft.GetDay() == tNow.GetDay())
				return FALSE;
			int	nDayOfWeek = tNow.GetDayOfWeek();
			if (1 == nDayOfWeek || 7 == nDayOfWeek)
				return FALSE;

			BOOL	bEmpty	= FALSE; // file.EmptyAll();
			file.Close();

			if (!bEmpty)
				return ::DeleteFile(lpszFileName);
			return TRUE;
		}
		else
		{
			file.Close();
			return ::DeleteFile(lpszFileName);
		}
	}

	return FALSE;
}

static CSPMutex g_mutexClkFile;

BOOL CTSKFile::EmptyAll()
{
	CSPMutex::Scoped locker(g_mutexClkFile);

	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return FALSE;

	// 顺序寻找
	DWORD	dwCount	= 0;
	for (DWORD i=0; i<m_header.m_dwIndexRecordCount; i++)
	{
		DWORD	dwPosIndex	= m_header.m_dwPosFirstIndex + m_header.m_dwIndexRecordSize * i;
		if (m_file.GetPosition() != dwPosIndex)
			m_file.Seek(dwPosIndex, CSPFile::begin);

		CLK_INDEXRECORD	index;
		if (sizeof(index) != m_file.Read(&index,sizeof(index)))
			return FALSE;
		if (CLK_INDEXRECORD_MAGIC != index.m_dwMagic)
			return FALSE;
		if (strlen(index.m_szCode) <= 0)
			continue;
		
		EmptyBlockChain(index.m_dwPosFirstBlock);
		index.m_dwDataRecordCountTotal	= 0;
		m_file.Seek(dwPosIndex, CSPFile::begin);
		m_file.Write(&index, sizeof(index));

		dwCount	++;
	}

	m_file.Flush();
	SP_ASSERT(dwCount == m_header.m_dwStockCount);
	return dwCount > 0; // == m_header.m_dwStockCount;
}

// 保存数据,并修改相应索引信息
DWORD CTSKFile::StoreDataRecord(DWORD dwMarket, const char * szCode,
							void * pData, DWORD dwDataElementSize, DWORD dwDataElementCount,
							BOOL bOverWrite)	// 返回成功保存记录数
{
	CSPMutex::Scoped locker(g_mutexClkFile);

	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return 0;

	CLK_INDEXRECORD	index;
	DWORD	dwPosIndexFind	= -1;
	if (!GetDataInfo(dwMarket, szCode, index, dwPosIndexFind, TRUE))
		return 0;

	if (bOverWrite)
	{
		EmptyBlockChain(index.m_dwPosFirstBlock);
		index.m_dwDataRecordCountTotal	= 0;
	}

	if (-1 == index.m_dwPosFirstBlock || 0 == index.m_dwPosFirstBlock)
		index.m_dwPosFirstBlock	= GetFirstBlankBlockPos(TRUE, TRUE);
	DWORD	dwCount = WriteData(index.m_dwPosFirstBlock, pData, dwDataElementSize, dwDataElementCount, FALSE);
	index.m_dwDataRecordCountTotal	+= dwCount;
	SetDataInfo(dwPosIndexFind, index, FALSE);

	// m_file.Flush();
	return dwCount;
}

// 得到某一股票的数据记录数	
DWORD CTSKFile::GetDataRecordCount(DWORD dwMarket, const char * szCode)
{
	CSPMutex::Scoped locker(g_mutexClkFile);

	CLK_INDEXRECORD	index;
	DWORD	dwPosIndexFind	= -1;
	if (GetDataInfo(dwMarket, szCode, index, dwPosIndexFind, FALSE))
		return index.m_dwDataRecordCountTotal;
	return 0;
}

// 读取某一股票的数据记录
DWORD CTSKFile::LoadDataRecord(DWORD dwMarket, const char * szCode,
							void * pData, DWORD dwDataElementSize, DWORD dwMaxDataElement)// 返回成功读取记录数
{
	CSPMutex::Scoped locker(g_mutexClkFile);

	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return 0;

	CLK_INDEXRECORD	index;
	DWORD	dwPosIndexFind	= -1;
	if (!GetDataInfo(dwMarket, szCode, index, dwPosIndexFind, FALSE))
		return 0;

	if (dwMaxDataElement < index.m_dwDataRecordCountTotal)
		return 0;

	return ReadData(index.m_dwPosFirstBlock, pData, dwDataElementSize, dwMaxDataElement);
}

DWORD CTSKFile::Hash(LPCTSTR key, DWORD dwMax)
{
	DWORD dwHash = 0;
	while (*key)
		dwHash = (dwHash<<5) + dwHash + *key++;
	return dwHash % dwMax;
}

// 得到某一股票的索引区信息,如果bAddIfNotExists并且不存在,则添加
BOOL CTSKFile::GetDataInfo(	DWORD dwMarket, const char * szCode, CLK_INDEXRECORD & idxRet, DWORD & dwPosIndexFind, BOOL bAddIfNotExists)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return FALSE;

	// 是否当前Cache
	if (m_CurIndexRecord.m_dwMarket == dwMarket
		&& 0 == strcmp(m_CurIndexRecord.m_szCode, szCode))
	{
		idxRet			= m_CurIndexRecord;
		dwPosIndexFind	= m_dwPosCurIndex;
		return TRUE;
	}

	DWORD	posBegin	= Hash(szCode, m_header.m_dwIndexRecordCount);
	// Hash顺序寻找
	for (DWORD i=posBegin; i<m_header.m_dwIndexRecordCount; i++)
	{
		DWORD	dwPosIndex	= m_header.m_dwPosFirstIndex + m_header.m_dwIndexRecordSize * i;
		if (m_file.GetPosition() != dwPosIndex)
			m_file.Seek(dwPosIndex, CSPFile::begin);
		 
		CLK_INDEXRECORD	index;
		if (sizeof(index) != m_file.Read(&index,sizeof(index))
			|| CLK_INDEXRECORD_MAGIC != index.m_dwMagic)
		{
			SP_ASSERT(FALSE);
			return FALSE;
		}
		if (dwMarket == index.m_dwMarket
			&& 0 == strcmp(szCode, index.m_szCode))
		{
			idxRet				= index;
			dwPosIndexFind		= dwPosIndex;
			m_CurIndexRecord	= index;
			m_dwPosCurIndex		= dwPosIndex;
			return TRUE;
		}
		if (0 == strlen(index.m_szCode))
		{
			if (bAddIfNotExists)
			{
				index.m_dwMarket	= dwMarket;
				strncpy(index.m_szCode, szCode, min(sizeof(index.m_szCode)-1,strlen(szCode)));
				index.m_dwDataRecordCountTotal	= 0;
				index.m_dwPosFirstBlock	= GetFirstBlankBlockPos(TRUE, TRUE);

				m_file.Seek(dwPosIndex, CSPFile::begin);
				m_file.Write(&index, sizeof(index));

				// 文件头
				m_header.m_dwStockCount	+= 1;
				m_file.Seek(0, CSPFile::begin);
				m_file.Write(&m_header, sizeof(m_header));
				// m_file.Flush();

				// return
				idxRet				= index;
				dwPosIndexFind		= dwPosIndex;
				m_CurIndexRecord	= index;
				m_dwPosCurIndex		= dwPosIndex;
				return TRUE;
			}
			return FALSE;
		}

		// 循环
		if (m_header.m_dwIndexRecordCount-1 == i)
			i = -1;
		if (posBegin-1 == i)
			break;
	}

	return FALSE;
}

// 保存某一股票的索引区信息
BOOL CTSKFile::SetDataInfo(	DWORD dwPosIndex, CLK_INDEXRECORD idx, BOOL bFlush)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return FALSE;

	// 是否当前Cache
	if (m_CurIndexRecord.m_dwMarket == idx.m_dwMarket
		&& 0 == strcmp(m_CurIndexRecord.m_szCode, idx.m_szCode))
	{
		m_CurIndexRecord	= idx;
	}

	if (-1 != dwPosIndex)
	{
		m_file.Seek(dwPosIndex, CSPFile::begin);
		m_file.Write(&idx, sizeof(idx));
		if (bFlush)
			m_file.Flush();
		return TRUE;
	}

	return FALSE;
}

// 得到某一空数据块
DWORD CTSKFile::GetFirstBlankBlockPos(BOOL bAddIfNotExists, BOOL bUseIt)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return -1;

	DWORD	dwPosBlock	= m_header.m_dwPosFirstBlankBlock;
	if (-1 != dwPosBlock && 0 != dwPosBlock)
	{
		m_file.Seek(dwPosBlock, CSPFile::begin);
		
		CLK_BLOCKHEADER	bheader;
		if (sizeof(bheader) == m_file.Read(&bheader,sizeof(bheader)))
		{
			SP_ASSERT(CLK_BLOCKHEADER_MAGIC == bheader.m_dwMagic);
			SP_ASSERT(!bheader.m_bUsed);

			if (bUseIt)
			{
				bheader.m_bUsed	= bUseIt;
				bheader.m_dwDataRecordCount	= 0;
				bheader.m_dwPosNextBlock	= -1;
				m_file.Seek(dwPosBlock, CSPFile::begin);
				m_file.Write(&bheader, sizeof(bheader));
			
				m_header.m_dwPosFirstBlankBlock	= bheader.m_dwPosNextBlock;
				m_file.Seek(0, CSPFile::begin);
				m_file.Write(&m_header, sizeof(m_header));
				// m_file.Flush();
			}
			return dwPosBlock;
		}
	}

	// Add
	if (bAddIfNotExists)
	{
		SP_ASSERT(bUseIt);	// Must Use It

		DWORD	dwDataSize = m_header.m_dwDataRecordSize*m_header.m_dwRecordPerBlock;
		if (dwDataSize <= 0)
			return -1;

		m_file.SeekToEnd();
		dwPosBlock	= m_file.GetPosition();

		CLK_BLOCKHEADER	bheader;
		memset(&bheader, 0, sizeof(bheader));
		bheader.m_dwMagic	= CLK_BLOCKHEADER_MAGIC;
		bheader.m_bUsed		= bUseIt;
		bheader.m_dwPosNextBlock	= -1;
		bheader.m_dwPosFirstRecord	= dwPosBlock + sizeof(bheader);
		m_file.Write(&bheader, sizeof(bheader));
		char	* temp	= new char[dwDataSize];
		if (!temp)
			return -1;
		memset(temp, 0, m_header.m_dwDataRecordSize);
		m_file.Write(temp, dwDataSize);
		delete	[] temp;
		// m_file.Flush();
	}

	return dwPosBlock;
}

// 清空数据Block链中的数据,并将除第一个Block外的其他Block置为未用
DWORD CTSKFile::EmptyBlockChain(DWORD dwPosFirstBlock)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return FALSE;

	DWORD	dwCount	= 0;
	DWORD	dwPosBlock	= dwPosFirstBlock;

	while(-1 != dwPosBlock && 0 != dwPosBlock)
	{
		m_file.Seek(dwPosBlock, CSPFile::begin);

		DWORD	dwPosNextBlock	= -1;
		CLK_BLOCKHEADER	bheader;
		if (sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
			|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic)
		{
			SP_ASSERT(FALSE);
		}
		else
		{
			dwPosNextBlock	= bheader.m_dwPosNextBlock;
		}

		// Empty it
		bheader.m_bUsed	= (dwPosFirstBlock == dwPosBlock);	// 第一块继续使用
		bheader.m_dwDataRecordCount	= 0;
		bheader.m_dwPosNextBlock	= -1;
		if (!bheader.m_bUsed)
			bheader.m_dwPosNextBlock	= m_header.m_dwPosFirstBlankBlock;
		m_file.Seek(dwPosBlock, CSPFile::begin);
		m_file.Write(&bheader, sizeof(bheader));
		
		// 加入Blank Block Chain
		if (!bheader.m_bUsed)
		{
			m_header.m_dwPosFirstBlankBlock	= dwPosBlock;
			m_file.Seek(0, CSPFile::begin);
			m_file.Write(&m_header, sizeof(m_header));
		}
		// m_file.Flush();
		dwCount	++;

		dwPosBlock	= dwPosNextBlock;
	}
	
	return dwCount;
}

// 读数据记录
DWORD CTSKFile::ReadData(DWORD dwPosBlock, void * pData, DWORD dwDataElementSize, DWORD dwMaxDataElement)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return FALSE;

	if (NULL == pData || dwMaxDataElement == 0)
		return 0;

	DWORD	dwCount	= 0;

	while(-1 != dwPosBlock && 0 != dwPosBlock)
	{
		m_file.Seek(dwPosBlock, CSPFile::begin);

		CLK_BLOCKHEADER	bheader;
		if (sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
			|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic)
		{
			SP_ASSERT(FALSE);
			return dwCount;
		}
		
		for (DWORD i=0; i<bheader.m_dwDataRecordCount; i++)
		{
			DWORD	dwPos	= bheader.m_dwPosFirstRecord + i * m_header.m_dwDataRecordSize;
			if (m_file.GetPosition() != dwPos)
				m_file.Seek(dwPos, CSPFile::begin);
			m_file.Read(((BYTE *)pData)+dwDataElementSize*dwCount, min(dwDataElementSize,m_header.m_dwDataRecordSize));
			dwCount ++;
			if (dwCount >= dwMaxDataElement)
				return dwCount;
		}
		
		dwPosBlock	= bheader.m_dwPosNextBlock;
	}
	
	return dwCount;
}

// 写数据记录
DWORD CTSKFile::WriteData(DWORD dwPosBlock, void * pData, DWORD dwDataElementSize, DWORD dwDataElementCount, BOOL bFlush)
{
	SP_ASSERT(CSPFile::hFileNull != m_file.m_hFile);
	if (CSPFile::hFileNull == m_file.m_hFile)
		return 0;

	SP_ASSERT(-1 != dwPosBlock && 0 != dwPosBlock);
	if (-1 == dwPosBlock || 0 == dwPosBlock)
		return 0;

	DWORD	dwCount	= 0;

	while(dwCount < dwDataElementCount && -1 != dwPosBlock && 0 != dwPosBlock)
	{
		m_file.Seek(dwPosBlock, CSPFile::begin);

		CLK_BLOCKHEADER	bheader;
		if (sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
			|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic)
		{
			SP_ASSERT(FALSE);
			return dwCount;
		}

		if (-1 != bheader.m_dwPosNextBlock && 0 != bheader.m_dwPosNextBlock)
		{
			SP_ASSERT(bheader.m_dwDataRecordCount == m_header.m_dwRecordPerBlock);
			if (bheader.m_dwDataRecordCount == m_header.m_dwRecordPerBlock)
			{
				dwPosBlock	= bheader.m_dwPosNextBlock;
				continue;
			}
		}

		// Write
		DWORD	dwCountOld	= dwCount;
		for (DWORD i=bheader.m_dwDataRecordCount; i<m_header.m_dwRecordPerBlock; i++)
		{
			DWORD	dwPos	= bheader.m_dwPosFirstRecord + i * m_header.m_dwDataRecordSize;
			if (m_file.GetPosition() != dwPos)
				m_file.Seek(dwPos, CSPFile::begin);
			m_file.Write(((BYTE *)pData)+dwDataElementSize*dwCount, min(dwDataElementSize,m_header.m_dwDataRecordSize));
			dwCount ++;
			if (dwCount >= dwDataElementCount)
				break;
		}
		
		// 修改Block Header
		bheader.m_bUsed	= TRUE;
		bheader.m_dwDataRecordCount	+= (dwCount-dwCountOld);
		bheader.m_dwPosNextBlock	= -1;
		if (dwCount < dwDataElementCount)
			bheader.m_dwPosNextBlock	= GetFirstBlankBlockPos(TRUE, TRUE);
		m_file.Seek(dwPosBlock, CSPFile::begin);
		m_file.Write(&bheader, sizeof(bheader));

		// 新Block
		dwPosBlock	= bheader.m_dwPosNextBlock;
	}

	if (bFlush)
		m_file.Flush();
	return dwCount;
}

 

CFile

CFile	file;
	CString	sFileName	=	AfxGetProfile().GetWorkDirectory() + szUpgradeFileName;
	if( file.Open( sFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite) )
CFile	file;
	CString	sFileName	=	AfxGetProfile().GetWorkDirectory() + szUpgradeFileName;
	if( file.Open( sFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite) )
CFile	file;
					if (file.Open(pHeader->m_File.m_szFileName,CFile::modeRead))
					{
						ASSERT(file.GetLength() == pHeader->m_File.m_dwLen);
						nPacketNum	=	(int)(file.GetLength()/sizeof(RCV_HISTORY_STRUCTEx));
						if (nPacketNum > 0)
							pDay = new RCV_HISTORY_STRUCTEx[nPacketNum];
						if (pDay)
							file.Read(pDay, sizeof(RCV_HISTORY_STRUCTEx)*nPacketNum);
						file.Close();
					}
CFile::modeCreate    让构造器创建一个新文件,如果那个文件已经存在,把那个文件的长度重设为0
CFile::modeNoTruncate    可以同modeCreate. 一起用,如果要创建的文件已经存在,并不把它长度设置为0,因而这个文件获取或者作为一个新建文件或者作为一个已存在文件打开。这个功能往往很好用,比如说,当你需要打开一个设置文件,但是你并不清楚这个文件是否已经存在。
CFile::modeRead 打开文件仅仅供读
CFile::modeReadWrite    打开文件供读写
CFile::modeWrite   打开文件只供写
CFile::modeNoInherit    阻止这个文件被子进程继承
CFile::shareDenyNone 打开这个文件同时允许其它进程读写这个文件。如果文件被其它进程以incompatibility模式打开,这是create操作会失败。
CFile::shareDenyRead   打开文件拒绝其它任何进程读这个文件。如果文件被其它进程用compatibility模式或者是读方式打开,create操作失败。
CFile::shareDenyWrite   打开文件拒绝其它任何进程写这个文件。如果文件被其它进程用compatibility模式或者是写方式打开,create操作失败。
CFile::shareExclusive   以独占方式打开这个文件,不允许其它进程读写这个文件。 Construction fails if the file has been opened in any other mode for read or write access, even by the current process.
CFile::shareCompat    这个标志在32位的MFC中无效。 This flag maps to CFile::shareExclusivewhen used in CFile::Open.
CFile::typeText   设置成对回车换行对有特殊处理的文本模式(仅用在派生类中)
CFile::typeBinary    设置二进制模式(仅用在派生类中)

CFile Class-docs.microsoft.com