概要: 1,通过分析Header提取编码 2,通过分析BOM(Byte Order Mark)提取编码 3,通过分析页面的meta提取编码 4,通过字节流分析检测编码 正文: 总结一下。目前有四种方法 1,通过分析Header提取编码。 这个也是比较简单。也是大家常用的,不过既然是总结。那还是帖一下代码吧。
WebRequest webRequest = WebRequest.Create(url) ; HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse() ; Regex reg_charset = new Regex(@"charset/b/s*=/s*(?<charset>[^""]*)") ; WebHeaderCollection headers = webResponse.Headers ; string encodingName = string.Empty; string contentType = headers["Content-Type"]; if (contentType.IndexOf("charset") > 0 && reg_charset.IsMatch(ContentType)) { encodingName = reg_charset.Match(contentType).Groups["charset"].Value; }
2,通过分析BOM(Byte Order Mark)提取编码
通过BOM检测编码
string encodingName = string.Empty; WebRequest webRequest = WebRequest.Create(url); HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); byte[] htmlByte = GetByteContent(stream); string codingName = string.Empty; Encoding encoding = Encoding.UTF8; byte[] bomByte = encoding.GetPreamble(); if (htmlByte.Length > bomByte.Length && htmlByte[0] == bomByte[0] && htmlByte[1] == bomByte[1] && htmlByte[2] == bomByte[2]) { codingName = "utf-8"; } encoding = Encoding.Unicode; bomByte = encoding.GetPreamble(); if (codingName == string.Empty && htmlByte.Length > bomByte.Length && htmlByte[0] == bomByte[0] && htmlByte[1] == bomByte[1]) { codingName = "unicode"; } encoding = Encoding.UTF32 ; bomByte = encoding.GetPreamble(); if (codingName == string.Empty && htmlByte.Length > bomByte.Length && htmlByte[0] == bomByte[0] && htmlByte[1] == bomByte[1] && htmlByte[2] == bomByte[2] && htmlByte[3] == bomByte[3]) { codingName = "utf-32"; } encoding = Encoding.BigEndianUnicode ; bomByte = encoding.GetPreamble(); if (codingName == string.Empty && htmlByte.Length > bomByte.Length && htmlByte[0] == bomByte[0] && htmlByte[1] == bomByte[1]) { codingName = "utf-16"; }
说明:上面的用到的GetByteContent方法,在3中有; 3,通过分析页面的meta提取编码 这个也是大家常用。但是这里不需要抓两次。一次就可以分析了
通过Meta提取编码
string encodingName = string.Empty ; WebRequest webRequest = WebRequest.Create(url); HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); byte[] htmlByte = GetByteContent(stream); stream.Close(); string temp = Encoding.GetEncoding("utf-8").GetString(htmlByte) ; string reg_charset = "(<meta[^>]*charset=(?<charset>[^>'/"]*)[//s//S]*?>)|(xml[^>]+encoding=(/"|')*(?<charset>[^>'/"]*)[//s//S]*?>)"; Regex r = new Regex(reg_charset, RegexOptions.IgnoreCase); Match m = r.Match(temp); encodingName = (m.Captures.Count != 0) ? m.Result("${charset}") : ""; string html = Encoding.GetEncoding(encodingName).GetString(htmlByte) ; //GetByteContent函数 private byte[] GetByteContent(Stream stream) { ArrayList arBuffer = new ArrayList(); byte[] buffer = new byte[1024]; int offset = 1024; int count = stream.Read(buffer, 0, offset); while (count > 0) { for (int i = 0; i < count; i++) { arBuffer.Add(buffer[i]); } count = stream.Read(buffer, 0, offset); } return (byte[])arBuffer.ToArray(System.Type.GetType("System.Byte")); }
4,通过字节流分析检测编码 就是一个byte一个byte的分析。网上的高手太多了,我这等菜鸟就不在这里献丑了。 已经有网友写出来了。高手
Lion出品。2K多行代码。;)*—¥……#……#%…… 我测试下。效果不错!可以从下面的URL获得需要的信息
http://www.cnblogs.com/lion.net/archive/2005/02/24/108395.html
5,一点问题 我在测试中。通过 StreamReader sr = new StreamReader(stream, Encoding.GetEncoding("utf-8")); 和 StreamReader sr = new StreamReader(stream, Encoding.UTF8); 结果竟然是不同的(前者正常,后者乱码)。 而Encoding.UTF8.Equals(Encoding.GetEncoding("utf-8"))是true 有那位朋友知道原因的。诚请指教。thanks!