程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Text文檔編碼識別方法,text文檔編碼

Text文檔編碼識別方法,text文檔編碼

編輯:關於.NET

Text文檔編碼識別方法,text文檔編碼


Text文檔編碼識別方法

  在做文檔讀取的時候,時常碰到編碼格式不正確的問題,而要怎麼樣正確識別文檔的編碼格式,成了很多程序員的一塊心病,今天我就要試著治好這塊心病,這段代碼的濃縮來自上千萬文檔的數據分析所得,可靠率極其高。

  應朋友要求,需要幫他做一個文章操作工具,既然想操作,就有文件的讀取和修改,本來花費幾個小時信心滿滿把程序交給朋友的時候,朋友突然來了句,很多文章打開出現亂碼的情況,我哩個去,像是晴天霹雳深深的擊在我的心窩裡,我突然想到了文件編碼問題,而這個問題,我曾經無數次的嘗試,最終都以失敗而告終,每次嘗試,只不過是減少了錯誤概率的出現,但是還不足以彌補文件編碼格式分析完全的正確,而這次,朋友又提出來編碼問題,我瞬間凌亂了。

  如果不把這個問題解決,給朋友做的工具等於沒有任何作用,我TM前兩天還吃人家一頓大餐,難道還能吐出來嗎?這個搞不定,面子就丟大了,無奈之下,我詢問了朋友那裡有多少文件?得到答復:好幾千萬。瞬間我眼光放亮了,那就海量數據分析吧。

  海量數據分析的時候,我使用的是一個笨方法,就是把所有文件頭數據讀取出來,比如讀取4個byte,然後將讀取的文件內容的前一百個字以(Unicode,UnicodeBigEndian,UTF8,ANSI等等)讀取出來,肉眼識別吧,比如

  public class Info{

    public int ch0;//第一個字符

    public int ch1;//第二個字符

    public int ch2;//第三個字符

    public int ch3;//第四個字符

    public string UnicodeStr;//前100個字

    public string UnicodeBigEndianStr;//前100個字

    public string UTF8Str;//前100個字

    public string ANSIStr;//前100個字

  }

 

然後使用lambda做排序,個人建議對UnicodeStr,UnicodeBigEndianStr,UTF8Str,ANSIStr這些做排序,因為可識別的字符編碼有一定的區間范圍,做排序後,可識別漢字的一定都堆在一起;

再有就是可以對 ch0,ch1,ch2,ch3,做詳細分類,看看它們之間都有什麼樣的關系,通過觀察,我也是能發現什麼的;通過歸納和總結,就得出了TEXT編碼的可識別方法,如下: 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace 文章操作工具
{
    public class TextHelper
    {
        public static System.Text.Encoding GetType(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            System.Text.Encoding r = GetType(fs);
            fs.Close();
            return r;
        }
        
        public static System.Text.Encoding GetType(FileStream fs)
        {
            /*
                                Unicode    
                                ------------------
                                255    254

                                ======================
                                UnicodeBigEndian
                                -------------------
                                254    255

                                ======================
                                UTF8
                                -------------------
                                34 228
                                34 229
                                34 230
                                34 231
                                34 232
                                34 233
                                239    187
             
                                ======================
                                ANSI
                                -------------------
                                34 176
                                34 177
                                34 179
                                34 180
                                34 182
                                34 185
                                34 191
                                34 194
                                34 196
                                34 198
                                34 201
                                34 202
                                34 205
                                34 206
                                34 208
                                34 209
                                34 210
                                34 211
                                34 213
                                196 167
                                202 213
                                206 228
            */
            BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default);
            byte[] ss = r.ReadBytes(3);
            int lef = ss[0];
            int mid = ss[1];
            int rig = ss[2];
            r.Close();
            /*  文件頭兩個字節是255 254,為Unicode編碼;
                文件頭三個字節  254 255 0,為UTF-16BE編碼;
                文件頭三個字節  239 187 191,為UTF-8編碼;*/
            if (lef == 255 && mid == 254)
            {
                return Encoding.Unicode;
            }
            else if (lef == 254 && mid == 255 && rig == 0)
            {
                return Encoding.BigEndianUnicode;
            }
            else if (lef == 254 && mid == 255)
            {
                return Encoding.BigEndianUnicode;
            }
            else if (lef == 239 && mid == 187 && rig == 191)
            {
                return Encoding.UTF8;
            }
            else if (lef == 239 && mid == 187)
            {
                return Encoding.UTF8;
            }
            else if (lef == 196 && mid == 167
                || lef == 206 && mid == 228
                || lef == 202 && mid == 213)
            {
                return Encoding.Default;
            }
            else
            {
                if (lef == 34)
                {
                    if (mid < 220) return Encoding.Default;
                    else return Encoding.UTF8;
                }
                else
                {
                    if (lef < 220) return Encoding.Default;
                    else return Encoding.UTF8;
                }
            }
        }
    }
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved