当前位置:   article > 正文

文本文件字符编码的探查_查看txt文件编码

查看txt文件编码

TXT文件字符存储编码格式,是指文件中的字符是以何种编码方式存储在磁盘中,一切以文本方式存储的文件都涉及这个问题,这些文件包括:.txt、 .PAS、 .HTML、 .XML等文件。如果不能正确识别存储编码,则在显示这些文件的时候会导致乱码。注意要区分字符存储编码和语言显示代码,HTML语言有一个语言显示代码,是指里面的文本以何种语言显示。

win10系统下的TXT文件存储字符编码有以下几种,ASCII,ANSI、UTF-8、带有BOM的UTF-8 、UTF-16LE、UTF-16BE。

一般情况下默认采用UTF-8编码存储的,这个编码是通用的,可以表达任何语言,但是也有缺点,就是编码长度不等长。下面说说,这几种编码的特点:

(1)   ASCII和ANSI编码:这两个编码是相互兼容的,如果字节的最高位是0(0-7F),二进制形如0XXX XXXX,则表达的是ASCII字符也就是USA-ASCII字符表内容。如果字节的最高位是1(80-FE),则就是ANSI(GBK)编码,注意,这时候是两个字节表达一个汉字,也就是说两个字节的最高位都是1的字节代表一个汉字,二进制形如1XXX XXXX, 1XXX XXXX 。因此ANSI字符编码是兼容ASCII编码的。

 在ANSI编码下,如果文本字符都是西文字符,则也可以认为是ASCII编码,当有连续高为是1的字节串出现的时候,这是可以判定为ANSI或GBK编码。GBK编码一定是两个高位均为1的字节表达一个汉字。ANSI则是一个字节表达一个字符,这个字节高为可以是1或0。

(2) UTF-8编码。utf-8是一种多字节编码的字符集,表示一个Unicode字符时,它可以是1个至多个字节。即在文本全部是ASCII字符时utf-8是和ASCII一致的(utf-8向下兼容ASCII)。最多6个字节表达一个字符,utf-8字节流如下所示:
             1字节:0xxxxxxx 
             2字节:110xxxxx 10xxxxxx 
             3字节:1110xxxx 10xxxxxx 10xxxxxx  ,一般汉字用这个3字节表达
             4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
             5字节:111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        注意,在UTF-8编码中,多种长度是混合存在的,即,一个字符串里面可能有1,2,3,等字节长度表达的字符同时存在 。因此在判断时候带来一定的难度。

(3)带有BOM的UTF-8,这个文本文件的头部带有三个先导标志字节0xEF, 0xBB,0xBF,通过判断这个标志,可以判断出这个文本文件是UTF-8编码。

(4)UTF-16LE,字节流是little endian ,这是标准UNICODE编码文本,是双字节等长编码。文本文件头部带有先导志字节0xFF 0xFE,通过判断这个标志,可以判断出这个文本文件是UTF-16LE编码。

(5) UTF-16BE, 字节流是big  endian,这是另一种UNICODE编码文本,是双字节等长编码。文本文件头部带有先导志字节0xFE  0xFF,通过判断这个标志,可以判断出这个文本文件是UTF-16BE编码。

 通过以上分析,ASCII,ANSI、UTF-8这种编码的文本文件,需要对字符串的字节流进行正确分析才能判断出编码方案,方法复杂,尤其是UTF-8编码。

带有BOM的UTF-8 、UTF-16LE、UTF-16BE这三个编码,只需要分析文本文件的头部字节就可以判断出来编码方案,方法简单。

以下是本人用delphi语言写的分析代码:

  1. type
  2. TTextFormat=(tfUSAASCII,tfANSI,tfUtf_8,tfUTF_16LE,tfUTF_16BE,tfUtf_8BOM);
  3. // 返回文本文件编码类型,sText返回标志字
  4. function GetTextFormat(const FileName: string; var sText:string):TTextFormat;
  5. function DetectUTF8Encoding2(const ss: array of byte; var Bn:Integer): TEncodeType;
  6. const
  7. TextFormatFlag:array[tfUTF_16LE..tfUtf_8BOM] of LongWord=($FFFE,$FEFF,$EFBBBF);
  8. TextFormatFlagT:array[TTextFormat] of string=('ASCII','ANSI(GBK)','UTF-8','UTF-16LE','UTF-16BE','UTF-8BOM');
  9. implementation
  10. {$R *.dfm}
  11. { TForm1 }
  12. function TForm1.GetTextFormat(const FileName: string; var sText: string): TTextFormat;
  13. var
  14. fTxtStream: TFileStream; //文件流
  15. w:Word;
  16. Count,i,NC:Integer;
  17. context:array[0..127] of byte;
  18. tt:array[TEncodeType] of boolean;
  19. aap:boolean; //方式判别
  20. begin
  21. sText:=''; aap:=False;
  22. tt[etUTF8]:=False; tt[etANSI]:=False; tt[etUSASCII]:=False;
  23. result:=tfAnsi;
  24. // NC:=128;
  25. fTxtStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
  26. try
  27. NC:=fTxtStream.Size ; //
  28. count:=fTxtStream.Read(context, 128); //一次读取不超过128个,返回实际读取字节数
  29. if not(aap) then
  30. begin
  31. if Count>=2 then //只判断文件长度超过2字节的文件的头部。
  32. begin
  33. w:=(word(context[0]) shl 8) or context[1]; // 组合成word
  34. case w of
  35. $FFFE:result:=tfUTF_16LE;
  36. $FEFF:result:=tfUTF_16BE;
  37. $EFBB: begin if Count>=3 then
  38. if context[2]=$BF then result:=tfUtf_8BOM
  39. else aap:=True //如果都不是,则需要进一步判断(USASCII, UTF8, ANSI编码 )
  40. end;
  41. else
  42. aap:=True;; //如果都不是,则需要进一步判断(USASCII, UTF8, ANSI编码 )
  43. end;
  44. end else aap:=True ; //如果都不是,则需要进一步判断(USASCII, UTF8, ANSI编码 )
  45. //格式化标志字
  46. if Result=tfUtf_8BOM
  47. then sText:='前导标志字-'+RightStr(inttohex(TextFormatFlag[Result]),6) ;
  48. if (Result=tfUTF_16LE) or (Result=tfUTF_16BE)
  49. then sText:='前导标志字-'+RightStr(inttohex(TextFormatFlag[Result]),4);
  50. end;
  51. //判断Txt文件的编码类型(USASCII, UTF8, ANSI编码
  52. //如果都不是,则需要进一步判断(USASCII, UTF8, ANSI编码 )
  53. if aap then
  54. begin
  55. //探查编码
  56. i:=Count;
  57. case DetectUTF8Encoding2(context,i) of
  58. etUTF8:begin
  59. tt[etUTF8]:=True; //如果探查到Utf_8 跳出循环
  60. // lbl1.Caption:=TextFormatFlagT[tfUtf_8];
  61. //Break ;
  62. end;
  63. etANSI: begin tt[etANSI]:=True; //继续探查
  64. // lbl3.Caption:=TextFormatFlagT[tfANSI];
  65. end;
  66. etUSASCII:begin tt[etUSASCII]:=True; //继续探查
  67. // lbl4.Caption:=TextFormatFlagT[tfUSAASCII];
  68. end;
  69. end;
  70. if tt[etUTF8] then result:=tfUtf_8
  71. else if tt[etANSI] then result:=tfANSI
  72. else if tt[etUSASCII] then result:=tfUSAASCII;
  73. sText:='无前导标志字,编码字节长度-'+IntToStr(i);
  74. end;
  75. finally
  76. FreeAndNil(fTxtStream);
  77. end;
  78. end;
  79. function TForm1.DetectUTF8Encoding2(const ss: array of byte; var Bn:Integer): TEncodeType;
  80. var
  81. i,sCount:Integer;
  82. sT:array[TEncodeType] of integer;
  83. begin
  84. Result := etUSASCII;
  85. sT[etUSASCII]:=0; sT[etANSI]:=0; sT[etUTF8]:=0; //初始化
  86. sCount:=bn; //字节实际长度
  87. bn:=0; i:=0; //初始化
  88. if sCount<=Length(ss) then
  89. while i<sCount do
  90. begin
  91. if (ss[i] in [$00..$7F]) then sT[etUSASCII]:=1 ; //USAASCII标记
  92. if (ss[i] in [$80..$FD]) and ((i+1)< sCount)
  93. then if (ss[i+1] in [$80..$FD])
  94. then sT[etANSI]:=2 //两字节ANSI,GBK字符
  95. else if sT[etANSI]=0 then sT[etANSI]:=1 ; //单字节ANSI字符
  96. if (ss[i] in [$C0..$DF]) and ((i+1) < sCount)
  97. then if (ss[i+1] in [$80..$BF])
  98. then if sT[etUTF8]<2 then sT[etUTF8]:=2 ; //是两字节UTF8
  99. if (ss[i] in [$E0..$EF]) and ((i+2) < sCount)
  100. then if ((ss[i+1] and ss[i+2]) in [$80..$BF]) //后两个字节是否是10开头·
  101. then if sT[etUTF8]<3 then sT[etUTF8]:=3; //是三字节UTF8
  102. if (ss[i] in [$F0..$F7]) and ((i+3) < sCount)
  103. then if ((ss[i+1] and ss[i+2] and ss[i+3]) in [$80..$BF]) //后三个字节是否是10开头
  104. then if sT[etUTF8]<4 then sT[etUTF8]:=4 ;//是四字节UTF8
  105. // lbl4.Caption:=lbl4.Caption+IntTostr(sT[etANSI]) ;
  106. inc(i); //读下一个字节
  107. end;
  108. if sT[etUTF8]>=2
  109. then begin
  110. result:=etUTF8 ; bn:=sT[etUTF8];
  111. end
  112. else if sT[etANSI]>=1
  113. then begin
  114. result:=etANSI ; bn:=sT[etANSI];
  115. end
  116. else if sT[etUSASCII]>=1
  117. then begin
  118. result:=etUSASCII; bn:=sT[etUSASCII];
  119. end;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/373637?site
推荐阅读
相关标签
  

闽ICP备14008679号