如何将文本文件转换成UTF-8格

解决方案 »

  1.   

    改文件头为EF BB BF,文件就是UTF-8格式的了。不过如果文件原来有内容,还需要把内容转换为UTF-8格式的,使用函数:WideCharToMultiByte和MultiByteToWideChar
      

  2.   

    什么是UTF8?  UTF8并不算是一种电脑编码,而是一种储存和传送的格式,如前所述,每个Unicode/UCS字符都以 2或4个bytes来储存,看看以下的比较:  以"I am Chinese"为例
       用ANSI储存:12 Bytes
       用Unicode/UCS2储存:24 Bytes + 2 Bytes(header)
       用UCS4储存:48 Bytes + 4 Bytes(header)  以"我是中国人"为例
       用ANSI储存:10 Bytes
       用Unicode/UCS2储存:10 Bytes + 2 Bytes(header)
       用UCS4储存:20 Bytes + 4 Bytes(header)  由此可见直接以Unicode/UCS的原始形式来储存是一种极大的浪费,而且也不利于互联网的传输(中文稍为合算一点^_^)。  有见及此,Unicode/UCS的压缩形式--UTF8出现了,套用官方网站的首句话『UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.』,由于UTF也适用于编码UCS,故亦可称为『UCS transformation formats (UTF)』  UTF8是以8bits即1Bytes为编码的最基本单位,当然也可以有基于16bits和32bits的形式,分别称为UTF16和UTF32,但目前用得不多,而UTF8则被广泛应用在文件储存和网络传输中。
    编码原理先看这个模板: UCS-4 range (hex.)      UTF-8 octet sequence (binary)
       0000 0000-0000 007F   0xxxxxxx
       0000 0080-0000 07FF   110xxxxx 10xxxxxx
       0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx   0001 0000-001F FFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
       0020 0000-03FF FFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
       0400 0000-7FFF FFFF   1111110x 10xxxxxx ... 10xxxxxx编码步骤:
    1) 首先确定需要多少个8bits(octets)
    2) 按照上述模板填充每个octets的高位bits
    3) 把字符的bits填充至x中,字符顺序:低位→高位,UTF8顺序:最后一个octet的最末位x→第一个octet最高位x
    4) 解码的原理一样。实例:(留意每个bit的颜色,粗体字为模板内容)UCS-4                            |UTF-8 
    -----------------------------------------------------------------------------
    HEX       BIN               Bytes| BIN                        HEX      Bytes 
    0000 000A 00001010          4    | 00001010                   0A       1 
    0000 0099 10011001          4    | 11000010 10011001          C2 99    2 
    0000 8D99 10001101 10011001 4    | 11101000 10110110 10011001 E8 B6 99 3   不知大家看懂了没有,其实不懂也无所谓,反正又不用自己算,程式可以完全代劳。  以UTF8格式储存的文件档首标识为EF BB BF。
    效率  从上述编码原理中得出的结论是:
       1.每个英文字母、数字所占的空间为1 Byte;
       2.泛欧语系、斯拉夫语字母占2 Bytes;
       3.汉字占3 Bytes。  由此可见UTF8对英文来说是个非常诱人的方案,但对中文来说则不太合算,无论用ANSI还是 Unicode/UCS2来编码都只用2 Bytes,但用UTF8则需要3 Bytes。  以下是一些统计资料,显示用UTF8来储存文件每个字符所需的平均字节:
       1.拉丁语系平均用1.1 Bytes;
       2.希腊文、俄文、阿拉伯文和希伯莱文平均用1.7 Bytes;
       3.其他大部份文字如中文、日文、韩文、Hindi(北印度语)用约3 Bytes;
       4.用超过4 Bytes的都是些非常少用的文字符号。官方网站:http://www.utf8.com/
      

  3.   

    EF BB BF只是UTF-8的表示方式,并不代表加上文档就会转化一般来说,从ascii到UNICODE需要使用编码表,window通过codepage来映射这种关系
    你可以通过WideCharToMultiByte和MultiByteToWideChar实现转化的操作,也可以通过
    Unicode.org上的对照表自己做codepageUTF-8是UNICODE的压缩方式,其实对英文比较经济,只需要一个字节的空间,而对于中文则
    需要3个字节,比UNICODE还费。转化的方式同样可以使用上面的2个函数,也可以载网上查相应的代码,不是很复杂。
    LPWSTR CStrHandler::TransA2W(LPCSTR pszSrc,UINT uCodePage)
    {
    LPWSTR lpwStr = NULL;
    try
    {
    int iLen = strlen(pszSrc);
    int iSize = sizeof(WCHAR) * iLen + 1;

    lpwStr = new WCHAR[iSize];
    iSize = ::MultiByteToWideChar(uCodePage, 0, pszSrc, 
    iLen + 1, lpwStr, iSize);
    }
    catch(...)
    {
    if(lpwStr != NULL)
    delete lpwStr;
    lpwStr = NULL;
    }
    return lpwStr;
    }LPTSTR CStrHandler::TransW2A(LPWSTR src,UINT uCodePage)
    {
    int nSrcLen = src != NULL ? wcslen(src) * 2 : 0;

    if (nSrcLen == 0) return NULL; LPTSTR dest = new CHAR[nSrcLen + 1];

    int result = ::WideCharToMultiByte(uCodePage, 0, src, -1,
    dest, nSrcLen + 1, NULL, NULL);
    if (result > 0)
    dest[result-1] = '\0'; return dest;
    }
    BY_HANDLE_FILE_INFORMATION fi;
    ::GetFileInformationByHandle(hFile,&fi);
    pBuf = new char[fi.nFileSizeLow + 1];

    ::SetFilePointer(hFile,0,0,FILE_BEGIN);
    ::ReadFile(hFile,pBuf,fi.nFileSizeLow,&dwSize,NULL);
    pBuf[dwSize] = '\0'; LPWSTR pData = TransA2W(pBuf, CP_ACP);
    dwSize = wcslen(pData) * sizeof(pData[0]);
    delete pBuf;
    pBuf = TransW2A(pData, CP_UTF8);
    dwSize = strlen(pBuf);
    ::SetFilePointer(hFile, 0, 0, FILE_BEGIN);
    ::WriteFile(hFile, pBuf, dwSize, &dwSize, NULL);