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 设置二进制模式(仅用在派生类中)