zoukankan      html  css  js  c++  java
  • 如何判断一个文本文件内容的编码格式 UTF-8 ? ANSI(GBK)

    转自:http://blog.csdn.net/jiangqin115/article/details/42684017

    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 }  
  • 相关阅读:
    一个屌丝程序猿的人生(一百零二)
    一个屌丝程序猿的人生(一百零一)
    一个屌丝程序猿的人生(一百)
    一个屌丝程序猿的人生(九十九)
    JavaEE开发之SpringMVC中的静态资源映射及服务器推送技术
    JavaEE开发之SpringMVC中的自定义拦截器及异常处理
    JavaEE开发之SpringMVC中的路由配置及参数传递详解
    JavaEE开发使用Maven管理的SpringMVC工程
    JavaEE开发之Spring中的条件注解、组合注解与元注解
    JavaEE开发之Spring中的多线程编程以及任务定时器详解
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/5832486.html
Copyright © 2011-2022 走看看