zoukankan      html  css  js  c++  java
  • C#自动识别文件编码

    在做导入微信商户后台退款数据时,无论怎么设置编码导出来都是乱码,后来在网上找了这个识别文件编码的代码,感觉不错。

    最后识别出来是gb2312,看来我还是太渣了,只能吃土了,竟然忘记了这个编码。

    下面,上代码。

      1 /// <summary>   
      2     /// 用于取得一个文本文件的编码方式(Encoding)。   
      3     /// </summary>   
      4     public class TxtFileEncoder
      5     {
      6         public TxtFileEncoder()
      7         {
      8             //   
      9             // TODO: 在此处添加构造函数逻辑   
     10             //   
     11         }
     12         /// <summary>   
     13         /// 取得一个文本文件的编码方式。如果无法在文件头部找到有效的前导符,Encoding.Default将被返回。   
     14         /// </summary>   
     15         /// <param name="fileName">文件名。</param>   
     16         /// <returns></returns>   
     17         public static Encoding GetEncoding(string fileName)
     18         {
     19             return GetEncoding(fileName, Encoding.Default);
     20         }
     21         /// <summary>   
     22         /// 取得一个文本文件流的编码方式。   
     23         /// </summary>   
     24         /// <param name="stream">文本文件流。</param>   
     25         /// <returns></returns>   
     26         public static Encoding GetEncoding(FileStream stream)
     27         {
     28             return GetEncoding(stream, Encoding.Default);
     29         }
     30         /// <summary>   
     31         /// 取得一个文本文件的编码方式。   
     32         /// </summary>   
     33         /// <param name="fileName">文件名。</param>   
     34         /// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>   
     35         /// <returns></returns>   
     36         public static Encoding GetEncoding(string fileName, Encoding defaultEncoding)
     37         {
     38             FileStream fs = new FileStream(fileName, FileMode.Open);
     39             Encoding targetEncoding = GetEncoding(fs, defaultEncoding);
     40             fs.Close();
     41             return targetEncoding;
     42         }
     43         /// <summary>   
     44         /// 取得一个文本文件流的编码方式。   
     45         /// </summary>   
     46         /// <param name="stream">文本文件流。</param>   
     47         /// <param name="defaultEncoding">默认编码方式。当该方法无法从文件的头部取得有效的前导符时,将返回该编码方式。</param>   
     48         /// <returns></returns>   
     49         public static Encoding GetEncoding(FileStream stream, Encoding defaultEncoding)
     50         {
     51             Encoding targetEncoding = defaultEncoding;
     52             if (stream != null && stream.Length >= 2)
     53             {
     54                 //保存文件流的前4个字节   
     55                 byte byte1 = 0;
     56                 byte byte2 = 0;
     57                 byte byte3 = 0;
     58                 byte byte4 = 0;
     59                 //保存当前Seek位置   
     60                 long origPos = stream.Seek(0, SeekOrigin.Begin);
     61                 stream.Seek(0, SeekOrigin.Begin);
     62 
     63                 int nByte = stream.ReadByte();
     64                 byte1 = Convert.ToByte(nByte);
     65                 byte2 = Convert.ToByte(stream.ReadByte());
     66                 if (stream.Length >= 3)
     67                 {
     68                     byte3 = Convert.ToByte(stream.ReadByte());
     69                 }
     70                 if (stream.Length >= 4)
     71                 {
     72                     byte4 = Convert.ToByte(stream.ReadByte());
     73                 }
     74                 //根据文件流的前4个字节判断Encoding   
     75                 //Unicode {0xFF, 0xFE};   
     76                 //BE-Unicode {0xFE, 0xFF};   
     77                 //UTF8 = {0xEF, 0xBB, 0xBF};   
     78                 if (byte1 == 0xFE && byte2 == 0xFF)//UnicodeBe   
     79                 {
     80                     targetEncoding = Encoding.BigEndianUnicode;
     81                 }
     82                 if (byte1 == 0xFF && byte2 == 0xFE && byte3 != 0xFF)//Unicode   
     83                 {
     84                     targetEncoding = Encoding.Unicode;
     85                 }
     86                 if (byte1 == 0xEF && byte2 == 0xBB && byte3 == 0xBF)//UTF8   
     87                 {
     88                     targetEncoding = Encoding.UTF8;
     89                 }
     90                 //恢复Seek位置         
     91                 stream.Seek(origPos, SeekOrigin.Begin);
     92             }
     93             return targetEncoding;
     94         }
     95 
     96 
     97 
     98         // 新增加一个方法,解决了不带BOM的 UTF8 编码问题   
     99 
    100         /// <summary>   
    101         /// 通过给定的文件流,判断文件的编码类型   
    102         /// </summary>   
    103         /// <param name="fs">文件流</param>   
    104         /// <returns>文件的编码类型</returns>   
    105         public static System.Text.Encoding GetEncoding(Stream fs)
    106         {
    107             byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 };
    108             byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 };
    109             byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM   
    110             Encoding reVal = Encoding.Default;
    111 
    112             BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
    113             byte[] ss = r.ReadBytes(4);
    114             if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00)
    115             {
    116                 reVal = Encoding.BigEndianUnicode;
    117             }
    118             else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41)
    119             {
    120                 reVal = Encoding.Unicode;
    121             }
    122             else
    123             {
    124                 if (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)
    125                 {
    126                     reVal = Encoding.UTF8;
    127                 }
    128                 else
    129                 {
    130                     int i;
    131                     int.TryParse(fs.Length.ToString(), out i);
    132                     ss = r.ReadBytes(i);
    133 
    134                     if (IsUTF8Bytes(ss))
    135                         reVal = Encoding.UTF8;
    136                 }
    137             }
    138             r.Close();
    139             return reVal;
    140 
    141         }
    142 
    143         /// <summary>   
    144         /// 判断是否是不带 BOM 的 UTF8 格式   
    145         /// </summary>   
    146         /// <param name="data"></param>   
    147         /// <returns></returns>   
    148         private static bool IsUTF8Bytes(byte[] data)
    149         {
    150             int charByteCounter = 1;  //计算当前正分析的字符应还有的字节数   
    151             byte curByte; //当前分析的字节.   
    152             for (int i = 0; i < data.Length; i++)
    153             {
    154                 curByte = data[i];
    155                 if (charByteCounter == 1)
    156                 {
    157                     if (curByte >= 0x80)
    158                     {
    159                         //判断当前   
    160                         while (((curByte <<= 1) & 0x80) != 0)
    161                         {
    162                             charByteCounter++;
    163                         }
    164                         //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X    
    165                         if (charByteCounter == 1 || charByteCounter > 6)
    166                         {
    167                             return false;
    168                         }
    169                     }
    170                 }
    171                 else
    172                 {
    173                     //若是UTF-8 此时第一位必须为1   
    174                     if ((curByte & 0xC0) != 0x80)
    175                     {
    176                         return false;
    177                     }
    178                     charByteCounter--;
    179                 }
    180             }
    181             if (charByteCounter > 1)
    182             {
    183                 throw new Exception("非预期的byte格式!");
    184             }
    185             return true;
    186         }
    187     }
  • 相关阅读:
    (七) rest_framework GenericAPIView/GenericViewSet/ ModelViewSet 解析
    (六) rest_framework 普通分页与加密分页
    (五) rest_framework 序列化与解析器源码实现
    (四) rest_framework 版本控制源码
    【使用 PySpark 分析 CSV 文件】
    安装 HBase1.3.6 on Windows 10 64 bit
    Spark Job 性能调优 (二)
    Spark RDD 分区到底怎么用?
    安装 Spyder python 开发环境 用于 Spark 数据分析 -word count
    安装 Spark on Windows 使用 PySpark
  • 原文地址:https://www.cnblogs.com/stulzq/p/6116627.html
Copyright © 2011-2022 走看看