当前位置:
首页 > Python基础教程 >
-
C#教程之C#判断文件编码——常用字法(5)
]{212,170},new byte[2]{201,231},new byte[2]{185,253},new byte[2]{199,176},
new byte[2]{195,230},new byte[2]{161,163},new byte[2]{163,172},new byte[2]{163,191},new byte[2]{163,161}
};
/// <summary>
/// 表示需要猜测编码的流。
/// </summary>
private Stream _thisStream;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="_canShuStream">参数流</param>
public StreamBianMaJianCe(Stream _canShuStream)
{
if (_canShuStream == null || _canShuStream.Length < 100)
{
throw new System.NullReferenceException("WenZiBianMaJianCe构造函数参数_canShuStream不能为空且长度不能小于100");
}
_thisStream = _canShuStream;
}
/// <summary>
/// 检测。
/// </summary>
/// <returns>流的编码</returns>
public Encoding JianCe()
{
byte[] _streamByte = DuQuWeiZiJie();
Encoding _returnEncoding = Encoding.UTF8;
//通过BOM头来判断编码,有BOM头也就没必要去猜了。
if (GenJuBomCaiBianMa(_streamByte, out _returnEncoding) == false)
{
_returnEncoding = CaiJieWenZiBianMa(_streamByte);
}
return _returnEncoding;
}
/// <summary>
/// 读取数据为字节。
/// </summary>
/// <returns></returns>
private byte[] DuQuWeiZiJie()
{
BinaryReader _BinaryReader = new BinaryReader(_thisStream);
byte[] _returnByte = new byte[_thisStream.Length];
//判断流的长度。
if (_thisStream.Length < (long)int.MaxValue)//小于整型值的情况
{
_BinaryReader.Read(_returnByte, 0, (int)_thisStream.Length);
}
else//大于整型值的情况
{
long _index = 0;
while (_index < _returnByte.Length)
{
_returnByte.CopyTo(_BinaryReader.ReadBytes(1024), _index);
_index = _index + 1024L;
}
}
return _returnByte;
}
/// <summary>
/// 根据BOM头返回编码格式。
/// </summary>
/// <param name="_streamByte">流的字节组。</param>
/// <returns></returns>
private bool GenJuBomCaiBianMa(byte[] _streamByte, out Encoding _ruCanEncoding)
{
//132 49 149 51 GB-18030
if (_streamByte[0] == 132 && _streamByte[1] == 49 && _streamByte[2] == 149 && _streamByte[3] == 51)
{
_ruCanEncoding = Encoding.GetEncoding("GB-18030");
return true;
}
//239 187 191 UTF-8
if (_streamByte[0] == 239 && _streamByte[1] == 187 && _streamByte[2] == 191)
{
_ruCanEncoding = Encoding.UTF8;
return true;
}
//254 255 Unicode
if (_streamByte[0] == 254 && _streamByte[1] == 255)
{
_ruCanEncoding = Encoding.Unicode;
return true;
}
if (_streamByte[0] == 255 && _streamByte[1] == 254)
{
//255 254 0 0 UTF-32
if (_streamByte[2] == 0 && _streamByte[3] == 0)
{
_ruCanEncoding = Encoding.UTF32;
}
//255 254 BigEndianUnicode
_ruCanEncoding = Encoding.BigEndianUnicode;
return true;
}
//43 47 118 UTF-7
if (_streamByte[0] == 43 && _streamByte[1] == 47 && _streamByte[2] == 118)
{
//[ 56 | 57 | 43 | 47 ]
if (_streamByte[3] == 56 || _streamByte[3] == 57 || _streamByte[3] == 43 || _streamByte[3] == 47)
{
_ruCanEncoding = Encoding.UTF7;
return true;
}
}
_ruCanEncoding = null;
return false;
}
/// <summary>
/// 猜解文字编码,适用于没有BOM头的情况。
/// </summary>
/// <param name="_streamByte">流的字节组。</param>
/// <returns></returns>
private Encoding CaiJieWenZiBianMa(byte[] _streamByte)
{
//按照中文世界编码使用概率确定猜解顺序。
//UTF8
if (GaoPinZiJianCeUFT8(_streamByte) == true)
{
return Encoding.UTF8;
}
//gb18030
if (GaoPinZiJianCeGB18030(_streamByte) == true)
{
return Encoding.GetEncoding("gb18030");
}
//UTF7
if (GaoPinZiJianCeUTF7(_streamByte) == true)
{
return Encoding.UTF7;
}
//UTF-32任何字符都以四个字节编码,必然可以被四整除
if (_streamByte.Length % 4 == 0)
{
if (GaoPinZiJianCeUTF32(_streamByte) == true)//UTF32
{
return Encoding.UTF32;
}
}
//BigEndianUnicode和Unicode任何字符都以二个字节编码,必然可以被二整除
if (_streamByte.Length % 2 == 0)
{
//Unicode
if (GaoPinZiJianCeUnicode(_streamByte) == true)
{
return Encoding.Unicode;
}
//BigEndianUnicod
if (GaoPinZiJianCeBigEndianUnicode(_streamByte) == true)
{
return Encoding.BigEndianUnicode;
}
}
//如果上述猜解都失败了,则返回UTF-8。
return Encoding.UTF8;
}
/// <summary>
/// 高频字检查法,UFT8编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeUFT8(byte[] _streamByte)
{
//命中次数。
int _mingZhongCiShu = 0;
foreach (byte[] bShuZu in _UTF8GaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i])
{
//如果首字节相等,则检查后面二个字节是否也相等
if ((i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[1])
&& (i + 2 < _streamByte.Length && _streamByte[i + 2] == bShuZu[2]))
{
_mingZhongCiShu++;
}
}
}
//UTF-8有一定几率与其他编码冲突,故而增加命中次数,减少误差。
if (_mingZhongCiShu > 2)
{
return true;
}
}
return false;
}
/// <summary>
/// 高频字检查法,Unicode编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeUnicode(byte[] _streamByte)
{
foreach (byte[] bShuZu in _UnicodeGaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i]
&& (i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[1]))
{
//如果首字节相等,则检查后面二个字节是否也相等
return true;
}
}
}
return false;
}
/// <summary>
/// 高频字检查法,UTF32编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeUTF32(byte[] _streamByte)
{
foreach (byte[] bShuZu in _UTF32GaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i])
{
//如果首字节相等,则检查后面二个字节是否也相等
if ((i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[1])
&& (i + 2 < _streamByte.Length && _streamByte[i + 2] == bShuZu[2])
&& (i + 3 < _streamByte.Length && _streamByte[i + 3] == bShuZu[3]))
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// 高频字检查法,UTF7编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeUTF7(byte[] _streamByte)
{
foreach (byte[] bShuZu in _UTF7GaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i])
{
//如果首字节相等,则检查后面二个字节是否也相等
if ((i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[1])
&& (i + 2 < _streamByte.Length && _streamByte[i + 2] == bShuZu[2])
&& (i + 3 < _streamByte.Length && _streamByte[i + 3] == bShuZu[3])
&& (i + 4 < _streamByte.Length && _streamByte[i + 4] == bShuZu[4]))
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// 高频字检查法,GB18030编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeGB18030(byte[] _streamByte)
{
foreach (byte[] bShuZu in _GB18030GaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i])
{
//如果首字节相等,则检查后面二个字节是否也相等
if ((i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[0]))
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// 高频字检查法,Unicode编码方法
/// </summary>
/// <param name="_streamByte">流字节组</param>
/// <returns></returns>
private bool GaoPinZiJianCeBigEndianUnicode(byte[] _streamByte)
{
foreach (byte[] bShuZu in _BigEndianUnicodeGaoPinZiFuBianMaLsit)
{
for (int i = 0; i < _streamByte.Length; i++)
{
//判断首编码是否相等
if (bShuZu[0] == _streamByte[i])
{
//如果首字节相等,则检查后面二个字节是否也相等
if ((i + 1 < _streamByte.Length && _streamByte[i + 1] == bShuZu[1]))
{
return true;
}
}
}
}
return false;
}
}
}
//使用示例 //爬虫判断网页编码 WebRequest _WebRequest = WebRequest.Create(@"https://www.cnblogs.com/j20171203/"); WebResponse _WebResponse = _WebRequest.GetResponse(); Stream _Stream = _WebResponse.GetResponseStream(); MemoryStream _MemoryStream = new MemoryStream(); const int bufferLength = 1024; byte[] buffer = new byte[bufferLength]; int actual = 1; while (true) { actual = _Stream.Read(buffer, 0, bufferLength); _MemoryStream.Write(buffer, 0, actual); if (actual == 0) { break; } } _MemoryStream.Position = 0; StreamBianMaJianCe _StreamBianMaJianCe = new StreamBianMaJianCe(_MemoryStream); Encoding _jieGuoEncoding = _StreamBianMaJianCe.JianCe(); _Stream.Close(); _Stream.Dispose(); _WebResponse.Close();
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式