博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何判断一个文本文件内容的编码格式 UTF-8 ? ANSI(GBK)
阅读量:4575 次
发布时间:2019-06-08

本文共 2985 字,大约阅读时间需要 9 分钟。

转自:

UTF-8编码的文本文档,有的带有BOM (Byte Order Mark, 字节序标志),即0xEF, 0xBB, 0xBF,有的没有。Windows下的txt文本编辑器在保存UTF-8格式的文本文档时会自动添加BOM到文件头。在判断这类文档时,可以根据文档的前3个字节来进行判断。然而BOM不是必需的,而且也不是推荐的。对不希望UTF-8文档带有BOM的程序会带来兼容性问题,例如Java编译器在编译带有BOM的UTF-8源文件时就会出错。而且BOM去掉了UTF-8一个期望的特性,即是在文本全部是ASCII字符时UTF-8是和ASCII一致的,即UTF-8向下兼容ASCII。

在具体判断时,如果文档不带有BOM,就无法根据BOM做出判断,而且IsTextUnicode API也无法对UTF-8编码的Unicode字符串做出判断。那在编程判断时就要根据UTF-8字符编码的规律进行判断了。
UTF-8是一种多字节编码的字符集,表示一个Unicode字符时,它可以是1个至多个字节,在表示上有规律:
1字节:0xxxxxxx
2字节:110xxxxx 10xxxxxx
3字节:1110xxxx 10xxxxxx 10xxxxxx
4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
这样就可以根据上面的特征对字符串进行遍历来判断一个字符串是不是UTF-8编码了。应该指出的是UTF-8字符串的各个字节的取值有一定的范围,并不是所有的值都是有效的UTF-8字符,但是一般的应用的情况下这样的判断在对足够长的字符串及是比较精确了,而且实现也比较简单。具体的字节取值范围可以参见"Unicode Explained"一书中的6.4.3。另外BOM本身也符合3字节UTF-8字符编码规律,所以本方法对带BOM的UTF-8字符串也是有效的。

 

1. 判断文本是否UTF编码

在下面程序中对最大3字节长的UTF-8字符进行了判断,在实际情况下,几乎所有能用到的UTF-8字符最长就是3个字节

1 bool IsUTF8(const void* pBuffer, long size)   2 {   3     bool IsUTF8 = true;   4     unsigned char* start = (unsigned char*)pBuffer;   5     unsigned char* end = (unsigned char*)pBuffer + size;   6     while (start < end)   7     {   8         if (*start < 0x80) // (10000000): 值小于0x80的为ASCII字符     9         {  10             start++;  11         }  12         else if (*start < (0xC0)) // (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符    13         {  14             IsUTF8 = false;  15             break;  16         }  17         else if (*start < (0xE0)) // (11100000): 此范围内为2字节UTF-8字符    18         {  19             if (start >= end - 1)  20             {  21                 break;  22             }  23   24             if ((start[1] & (0xC0)) != 0x80)  25             {  26                 IsUTF8 = false;  27                 break;  28             }  29   30             start += 2;  31         }  32         else if (*start < (0xF0)) // (11110000): 此范围内为3字节UTF-8字符    33         {  34             if (start >= end - 2)  35             {  36                 break;  37             }  38   39             if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80)  40             {  41                 IsUTF8 = false;  42                 break;  43             }  44   45             start += 3;  46         }  47         else  48         {  49             IsUTF8 = false;  50             break;  51         }  52     }  53   54     return IsUTF8;  55 }

2. 判断文件是否UTF-8编码:

1 bool CConvertCharset::IsUTF8File(const char* pFileName)   2 {   3     FILE *f = NULL;   4     fopen_s(&f, pFileName, "rb");   5     if (NULL == f)   6     {   7         return false;   8     }   9   10     fseek(f, 0, SEEK_END);  11     long lSize = ftell(f);  12     fseek(f, 0, SEEK_SET);  //或rewind(f);  13   14     char *pBuff = new char[lSize + 1];  15     memset(pBuff, 0, lSize + 1);  16     fread(pBuff, lSize, 1, f);  17     fclose(f);  18   19     bool bIsUTF8 = IsUTF8Text(pBuff, lSize);  20     delete []pBuff;  21     pBuff = NULL;  22   23     return bIsUTF8;  24 }

转载于:https://www.cnblogs.com/fnlingnzb-learner/p/5832486.html

你可能感兴趣的文章
实现ajax
查看>>
【C#文件夹锁】C#文件夹加锁小工具
查看>>
mysql 数据库路径
查看>>
web服务器负载均衡部署及实现
查看>>
13.JOIN
查看>>
省市县三级联动
查看>>
多IP地址--笔记
查看>>
react native开发日记
查看>>
Virtual Dom是什么
查看>>
阶乘之和
查看>>
Unable to instantiate receiver xxx.receiver.NetworkReceiver异常
查看>>
C++调用C#类库函数
查看>>
vs2013编译项目去掉warning信息
查看>>
ASP.NET MVC html help
查看>>
C# 时间比较方法DateTime.Compare
查看>>
三级菜单小练习
查看>>
vim 插件管理
查看>>
Guid函数
查看>>
java的加减乘除问题
查看>>
Android 系统常用的权限
查看>>