中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C# 小敘 Encoding

關(guān)于Encoder和Decoder

從字面意思上理解就是編碼和解碼,CLR有類似的,像UrlDecode()和UrlEncode()是對URL中的參數(shù)解碼編碼一樣。Encoder,Decoder這兩個是用來字符和字節(jié)之間的編碼和解碼的,是兩個類型,而且還是抽象的,所以我們不能直接實例化它,但是目前CLR中給我們使用的類型中沒有它們的派生類,不過CLR內(nèi)部實現(xiàn)里肯定有它們的派生類。比如說下面的DecoderNLS就被定義成了internal,做為調(diào)用者的我們是看不到的。Encoder和Decoder是在Encoding里以兩個虛方法出現(xiàn)的,GetEncoder()和GetDecoder(),派生類里有不同的實現(xiàn)。比較UTF-8里就返回UTF8Decoder。

[Serializable]
internal class UTF8Decoder : DecoderNLS, ISerializable
[Serializable]
internal class DecoderNLS : Decoder, ISerializable

public override Decoder GetDecoder()
{
    return new UTF8Decoder(this);
}

用法也比較簡單,下面代碼不詳細(xì)解釋了。


//Encoderstring test = "ABCDE1234測試";Console.WriteLine("The test of string is {0}", test);Encoding encoding = Encoding.UTF8;char[] source = test.ToCharArray();int strLength = test.Length;int len = encoding.GetEncoder().GetByteCount(source, 0, strLength, false);byte[] result = new byte[len];encoding.GetEncoder().GetBytes(source, 0, strLength, result, 0, false);Console.WriteLine("After Encoder,the byte of test is output below。");foreach (byte b in result){    Console.Write("{0:X}-", b);}Console.WriteLine();//DecoderConsole.Write("After Decoder,the string is ");int deslen = encoding.GetDecoder().GetCharCount(result, 0, result.Length);char[] des = new char[deslen];encoding.GetDecoder().GetChars(result, 0, result.Length, des, 0);foreach (char c in des){    Console.Write("{0}", c);}

也許有人看出來了,這和Encoding的編碼和解碼沒什么區(qū)別啊,Encoding還會更簡單,選擇更多些,為何我還要多創(chuàng)建兩個對象?是的,沒錯,如果對一塊完整的數(shù)據(jù)流,完全沒必要去創(chuàng)建這兩個對象,Encoding的功能已經(jīng)可以實現(xiàn)了,但是如果我們要操作的是文件流或網(wǎng)絡(luò)流,需要跨塊處理,比如每次我都從一個流中讀取5個字節(jié)進(jìn)行處理?看一下代碼就知道了

public static void Main(){    //臨時文件    string path = Path.GetTempFileName();    File.WriteAllText(path, "ABCDE1234測試∑我", new UTF8Encoding(false));    //創(chuàng)建Decoder對象    //Decoder dec = Encoding.UTF8.GetDecoder();    using (FileStream fs = File.OpenRead(path))    {        byte[] buffer;        int size;        //每次都讀取5個字節(jié)        buffer = new byte[5];        while ((size = fs.Read(buffer, 0, 5)) > 0)        {            //char[] chars = new char[dec.GetCharCount(buffer, 0, size)];            //dec.GetChars(buffer, 0, size, chars, 0);            char[] chars1 = Encoding.UTF8.GetChars(buffer, 0, size);            if (chars1.Length != 0)            {                //Console.Write("{0,-10}", new string(chars));                Console.Write("{0,-10}", new string(chars1));                Console.Write("字節(jié):");                PrintBytes(buffer, size);            }            Thread.Sleep(500);        }    }    Console.Read();}static void PrintBytes(byte[] bytes, int len){    for (int i = 0; i < len; i++)        Console.Write("{0:X2} ", bytes[i]);    Console.WriteLine();}

我們先將字符串"ABCDE1234測試∑我”用UTF-8編碼寫到一個臨時文件里,然后放到一個stream里,再對這個stream每次讀取5個字節(jié)的操作。我們可以看出來這個字符串轉(zhuǎn)化成字節(jié)的長度為1+1+1+1+1+1+1+1+1+3+3+3+3,讀取前5個是沒任何問題的,都是單字節(jié)字符。再讀接下來五個時就有問題了,第10個字符是一個多字節(jié)字符,其中的兩個字節(jié)要放下一次的讀取了,Encoding.GetChars()就不能正確識別了,第10個字符將被識別為亂碼,將會以為?顯示。

下面是打印的結(jié)果:

我們把注釋的代碼取消注釋后,再重新運行看一下結(jié)果,

Decoder dec = Encoding.UTF8.GetDecoder();

char[] chars = new char[dec.GetCharCount(buffer, 0, size)];

dec.GetChars(buffer, 0, size, chars, 0);

Console.Write("{0,-10}", new string(chars));

最左邊的是用Decoder解碼的,中間的是用Encoding解碼的

亂碼消失了,Decoder可以正確的得到我們想要的結(jié)果,而且Encoding卻有亂碼。為什么會這樣?

Encoder和Decoder 維護(hù)對 GetBytes() 和GetChars()的連續(xù)調(diào)用間的狀態(tài)信息,因此它可以正確地對跨塊的字符序列進(jìn)行編碼。Encoder 還保留數(shù)據(jù)塊結(jié)尾的尾部字符并將這些尾部字符用在下一次編碼操作中。例如,一個數(shù)據(jù)塊的末尾可能是一個不匹配的高代理項,而與其匹配的低代理項則可能位于下一個數(shù)據(jù)塊中。因此,DecoderEncoder 對網(wǎng)絡(luò)傳輸和文件操作很有用,這是因為這些操作通常處理數(shù)據(jù)塊而不是完整的數(shù)據(jù)流。StreamReader和SteamWriter關(guān)于讀和書的就是用Decoder和Encoder。

//StreamWriter

int count = this.encoder.GetBytes(this.charBuffer, 0, this.charPos, this.byteBuffer, 0, flushEncoder

//StreamReader

charIndex = this.decoder.GetChars(this.byteBuffer, 0, this.byteLen, this.charBuffer, charIndex);

 

中文的全角和半角問題

這個問題有人問過我,我查了一些資料。因為所有的字符在CLR中都是以Unicode-16編碼的,這個問題就比較好處理了,全角和半角的值它們相差65248,除了空格相差12256。所以全角的字符若是想轉(zhuǎn)換成半角除空格減12256外,其他相減65248便是相應(yīng)的半角。具體可以參考園子里的這篇博客:C#全角和半角轉(zhuǎn)換

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Gb2312Encoding 編碼轉(zhuǎn)換
Socket編程 編碼和解碼
Python3標(biāo)準(zhǔn)庫:codecs字符串編碼和解碼
ByteBuffer的心得
Node.js:Buffer淺談
圖片與二進(jìn)制之間的轉(zhuǎn)換
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服