写在开始
最近在做一个东东,遇到文件读取的问题,遂开始研究,使用C++读取文本文件比较简单,也是一个很好的切入点,所以进行了一些小实验。
这里仅仅举例,使用ANSI,UNICODE,UTF-8三种常用的文本文件作为示例。
关于文本文件的文件头
第一 ANSI文件的文件头为空,不需要处理;
第二 UNICODE文件的文件头为0xFF,0xFE共计两个字节,读取时需要偏移两个字节再行读取;
第三 UTF-8文件的文件头为0xEF,0xBB,0xBF共计三个字节,读取时需要偏移三个字节后再行读取;
关于文本文件类型的判断
根据文本文件的文件头,就可以判断文本文件的类型了。
假设有如下文件类型定义:
typedef enum FileType
{
ANSI = 0,
UNICODE,
UTF8,
}FILETYPE;
我们就可以根据上述特性,来判断文本文件的类型了,下面是一段示例代码:
FILETYPE GetTextFileType(const std::string & strFileName)
{
FILETYPE fileType = ANSI;
std::ifstream file;
file.open(strFileName.c_str(), std::ios_base::in);
bool bUnicodeFile = false;
if (file.good())
{
char szFlag[3] = {0};
file.read(szFlag, sizeof(char) * 3);
if ((unsigned char)szFlag[0] == 0xFF
&& (unsigned char)szFlag[1] == 0xFE)
{
fileType = UNICODE;
}
else if ((unsigned char)szFlag[0] == 0xEF
&& (unsigned char)szFlag[1] == 0xBB
&& (unsigned char)szFlag[2] == 0xBF)
{
fileType = UTF8;
}
}
file.close();
return fileType;
}
ANSI文本文件的读取
ANSI文本文件不需要进行文件头的处理,可以直接读取。
下面是简单示例:
char szBuf[FBLOCK_MAX_BYTES];
memset(szBuf, 0, sizeof(char) * FBLOCK_MAX_BYTES);
std::string strMessage;
FILE * fp = NULL;
fp = fopen(strFileName.c_str(), "rb");
if (fp != NULL)
{
// common file do not offset.
while(fread(szBuf, sizeof(char), FBLOCK_MAX_BYTES, fp) > 0)
{
strMessage += szBuf;
memset(szBuf, 0, sizeof(char) * FBLOCK_MAX_BYTES);
}
}
std::cout << strMessage << std::endl;
fclose(fp);
UNICODE文本文件读取
由于UNICODE普遍采用双字节来表示字符,因此读取时,当使用wchar_t类型来读取,使用fopen,fread来进行操作。
下面是简单示例:
wchar_t szBuf[FBLOCK_MAX_BYTES];
memset(szBuf, 0, sizeof(wchar_t) * FBLOCK_MAX_BYTES);
std::string strMessage;
FILE * fp = NULL;
fp = fopen(strFileName.c_str(), "rb");
if (fp != NULL)
{
// Unicode file should offset wchar_t bits(2 byte) from start.
fseek(fp, sizeof(wchar_t), 0);
while(fread(szBuf, sizeof(wchar_t), FBLOCK_MAX_BYTES, fp) > 0)
{
char szTemp[FBLOCK_MAX_BYTES] = {0};
UnicodeToANSI(szTemp, szBuf);
strMessage += szTemp;
memset(szBuf, 0, sizeof(wchar_t) * FBLOCK_MAX_BYTES);
}
}
std::cout << strMessage << std::endl;
fclose(fp);
UTF8文本文件的读取
UTF8是可变字节,使用单一字节读取比较合理,所以读取时,使用char作为基本类型。
下面是简单示例代码:
char szBuf[FBLOCK_MAX_BYTES];
memset(szBuf, 0, sizeof(char) * FBLOCK_MAX_BYTES);
std::string strMessage;
FILE * fp = NULL;
fp = fopen(strFileName.c_str(), "rb");
if (fp != NULL)
{
// UTF-8 file should offset 3 byte from start position.
fseek(fp, sizeof(char) * 3, 0);
while(fread(szBuf, sizeof(char), FBLOCK_MAX_BYTES, fp) > 0)
{
strMessage += szBuf;
memset(szBuf, 0, sizeof(char) * FBLOCK_MAX_BYTES);
}
}
std::cout << strMessage << std::endl;
fclose(fp);
后记
文本文件的读取并非一个大的问题,但是使用的较多,而各个开发部门一般使用成熟的库,开发人员很少可以接触到低层的东东。
当无力支持购买成熟库的时候,就需要自己来做些东西了,这里仅仅是一个开始。
附录:测试源代码
本文介绍了如何使用C++读取ANSI, UNICODE和UTF-8三种不同类型的文本文件,包括文件头处理、文件类型判断和读取示例代码。"
42621917,803112,Unity新UI系统:实用技巧与定制教程,"['Unity3D', '游戏开发', 'UI设计', '编辑器扩展', 'C#脚本']
2151

被折叠的 条评论
为什么被折叠?



