国产乱子伦无码精品小说_色花堂国产第一页_欧美韩国三级在线观看不卡_中国少妇×XXXX性裸交_在线无码成本人视频动漫

首頁 >資訊參考 >

當(dāng)前焦點(diǎn)!【踩坑記錄】字節(jié)流數(shù)據(jù)按照string的方式讀取然后按照string的方案存儲(chǔ),編碼導(dǎo)致二進(jìn)制數(shù)據(jù)發(fā)生變化,原理記錄

發(fā)布日期:2023-06-01 23:34:58 來源:博客園 分享
?

目錄

問題緣由

背后原理


(資料圖)

C#代碼示例

總結(jié)


問題緣由

由于公司需求,需要讀取游戲Redis數(shù)據(jù)做內(nèi)外網(wǎng)數(shù)據(jù)遷移,沒有與游戲組過多的溝通。 使用的數(shù)據(jù)類型是Hash, key是string,value是byte[]。以前對(duì)于編碼的理解是:計(jì)算機(jī)底層存儲(chǔ)的永遠(yuǎn)是01的二進(jìn)制數(shù)據(jù),編碼是一種對(duì)于計(jì)算機(jī)二進(jìn)制數(shù)據(jù)的字符映射,也就是約定好哪個(gè)值對(duì)應(yīng)哪個(gè)字符。是為了便于在顯示器上展示。

那么基于這個(gè)理解,我就以為 不需要關(guān)心存儲(chǔ)的數(shù)據(jù)類型,因?yàn)槲也恍枰玫綌?shù)據(jù),我只是負(fù)責(zé)做數(shù)據(jù)的搬運(yùn)。于是我用的是HGetAsync方法去讀的字符串。然后HSetAsync把數(shù)據(jù)存到另一個(gè)Redis。結(jié)果發(fā)現(xiàn)數(shù)據(jù)發(fā)生了編碼?;谖疑线厡?duì)于編碼的理解,也就是按照不同的編碼讀取字符串,只是顯示器上會(huì)亂碼,但是底層的01二進(jìn)制沒有發(fā)生變化,這次問題打破了我的認(rèn)知。

背后原理

當(dāng)一個(gè)byte[]在計(jì)算機(jī)中存儲(chǔ)時(shí),它就是以二進(jìn)制形式保存的。如果這個(gè)byte[]中的每一個(gè)字節(jié)代表的是ASCII碼(一個(gè)字節(jié)表示一個(gè)字符),那么它在不同的編碼下讀取應(yīng)該沒有問題。但是,如果它代表的是Unicode字符集(UTF-8和UTF-16等),那么在不同的編碼下讀取就會(huì)發(fā)生問題。因?yàn)椴煌木幋a方式對(duì)存儲(chǔ)方式和字節(jié)長度都有不同的要求。

以UTF-8為例,它對(duì)不同字符分配的位數(shù)不同。對(duì)于ASCII字符,UTF-8使用一個(gè)字節(jié)表示,而對(duì)于其他字符,它需要兩個(gè)字節(jié)、三個(gè)字節(jié)或四個(gè)字節(jié)來表示。因此,在按照UTF-8格式讀取一個(gè)byte[]時(shí),如果它的編碼確實(shí)是UTF-8,那么就可以讀取正確的字符。但是,如果重新以UTF-8的格式存儲(chǔ)它時(shí),就會(huì)按照UTF-8的編碼方式重新把這個(gè)字符轉(zhuǎn)換成二進(jìn)制。如果這個(gè)字符之前的編碼不是UTF-8,那么它在轉(zhuǎn)換為UTF-8的二進(jìn)制時(shí),就會(huì)變成不同的值,因此數(shù)據(jù)也就變了。

C#代碼示例
var data = Encoding.UTF32.GetBytes("愛");var word = Encoding.UTF8.GetString(data);var word1 = Encoding.UTF32.GetString(data);File.WriteAllText($@"{AppDomain.CurrentDomain.BaseDirectory}/code.txt", word);File.WriteAllText($@"{AppDomain.CurrentDomain.BaseDirectory}/code1.txt", word1);foreach (var d in File.ReadAllBytes($@"{AppDomain.CurrentDomain.BaseDirectory}/code.txt")){    Console.WriteLine(d);}Console.WriteLine("------------");foreach (var d in File.ReadAllBytes($@"{AppDomain.CurrentDomain.BaseDirectory}/code1.txt")){    Console.WriteLine(d);}

例如,我們有一個(gè)Unicode字符“愛”,其二進(jìn)制表示為:0000 0100 1110 0111。按照UTF-8編碼的規(guī)則,在存儲(chǔ)這個(gè)字符時(shí),我們需要使用3個(gè)字節(jié)的二進(jìn)制數(shù)據(jù):1110XXXX 10XXXXXX 10XXXXXX(X表示對(duì)應(yīng)字符的二進(jìn)制數(shù)據(jù)的高位)

我們將其存儲(chǔ)到一個(gè)byte[]中,再將其存儲(chǔ)到文件中。然后按照UTF-8的格式讀取,解析出Unicode字符“愛”,再將其按照UTF-8的格式存儲(chǔ)回文件。這時(shí),由于使用了UTF-8編碼,我們需要將Unicode字符“愛”轉(zhuǎn)換為UTF-8編碼的二進(jìn)制數(shù)據(jù),即,使用3個(gè)字節(jié)的二進(jìn)制數(shù)據(jù):11100100 10101110 10011111。

通過運(yùn)行代碼,可以看到,由于存儲(chǔ)使用了UTF-8編碼,而讀取和重新存儲(chǔ)又使用了UTF-8編碼,因此二進(jìn)制數(shù)據(jù)發(fā)生了變化。

總結(jié)

當(dāng)一個(gè)byte[]在計(jì)算機(jī)中存儲(chǔ)時(shí),它就是以二進(jìn)制形式保存的。如果這個(gè)byte[]中的每一個(gè)字節(jié)代表的是ASCII碼(一個(gè)字節(jié)表示一個(gè)字符),那么它在不同的編碼下讀取應(yīng)該沒有問題。但是,如果它代表的是Unicode字符集(UTF-8和UTF-16等),那么在不同的編碼下讀取就會(huì)發(fā)生問題。

?

標(biāo)簽:

Copyright ©  2015-2022 太平洋獸藥網(wǎng)  版權(quán)所有  備案號(hào):豫ICP備2022016495號(hào)-17   聯(lián)系郵箱:93 96 74 66 9@qq.com