【踩坑記錄】位元組流數據按照string的方式讀取然後按照string的方案存儲,編碼導致二進位數據發生變化,原理記錄

来源:https://www.cnblogs.com/xuyd/archive/2023/06/01/17450102.html
-Advertisement-
Play Games

在本篇博客中,我將介紹如何在WPF應用程式中使用OwinSelfHost和Swagger來創建自托管的Web API。我們將使用WPF作為我們的應用程式界面,OwinSelfHost來自托管我們的Web API,並使用Swagger來為我們的API生成文檔。 首先,確保你的電腦上已安裝了以下組件: ...


目錄

 

問題緣由

背後原理

C#代碼示例

總結


 

問題緣由

        由於公司需求,需要讀取游戲Redis數據做內外網數據遷移,沒有與游戲組過多的溝通。  使用的數據類型是Hash, key是string,value是byte[]。以前對於編碼的理解是:電腦底層存儲的永遠是01的二進位數據,編碼是一種對於電腦二進位數據的字元映射,也就是約定好哪個值對應哪個字元。是為了便於在顯示器上展示。

        那麼基於這個理解,我就以為 不需要關心存儲的數據類型,因為我不需要用到數據,我只是負責做數據的搬運。於是我用的是HGetAsync方法去讀的字元串。然後HSetAsync把數據存到另一個Redis。結果發現數據發生了編碼。基於我上邊對於編碼的理解,也就是按照不同的編碼讀取字元串,只是顯示器上會亂碼,但是底層的01二進位沒有發生變化,這次問題打破了我的認知。

 

背後原理

        當一個byte[]在電腦中存儲時,它就是以二進位形式保存的。如果這個byte[]中的每一個位元組代表的是ASCII碼(一個位元組表示一個字元),那麼它在不同的編碼下讀取應該沒有問題。但是,如果它代表的是Unicode字元集(UTF-8和UTF-16等),那麼在不同的編碼下讀取就會發生問題。因為不同的編碼方式對存儲方式和位元組長度都有不同的要求。

        以UTF-8為例,它對不同字元分配的位數不同。對於ASCII字元,UTF-8使用一個位元組表示,而對於其他字元,它需要兩個位元組、三個位元組或四個位元組來表示。因此,在按照UTF-8格式讀取一個byte[]時,如果它的編碼確實是UTF-8,那麼就可以讀取正確的字元。但是,如果重新以UTF-8的格式存儲它時,就會按照UTF-8的編碼方式重新把這個字元轉換成二進位。如果這個字元之前的編碼不是UTF-8,那麼它在轉換為UTF-8的二進位時,就會變成不同的值,因此數據也就變了。

 

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);
}
 

        例如,我們有一個Unicode字元“愛”,其二進位表示為:0000 0100 1110 0111。按照UTF-8編碼的規則,在存儲這個字元時,我們需要使用3個位元組的二進位數據:1110XXXX 10XXXXXX 10XXXXXX(X表示對應字元的二進位數據的高位)

        我們將其存儲到一個byte[]中,再將其存儲到文件中。然後按照UTF-8的格式讀取,解析出Unicode字元“愛”,再將其按照UTF-8的格式存儲迴文件。這時,由於使用了UTF-8編碼,我們需要將Unicode字元“愛”轉換為UTF-8編碼的二進位數據,即,使用3個位元組的二進位數據:11100100 10101110 10011111。

        通過運行代碼,可以看到,由於存儲使用了UTF-8編碼,而讀取和重新存儲又使用了UTF-8編碼,因此二進位數據發生了變化。

 

總結

        當一個byte[]在電腦中存儲時,它就是以二進位形式保存的。如果這個byte[]中的每一個位元組代表的是ASCII碼(一個位元組表示一個字元),那麼它在不同的編碼下讀取應該沒有問題。但是,如果它代表的是Unicode字元集(UTF-8和UTF-16等),那麼在不同的編碼下讀取就會發生問題。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文介紹基於**Python**中**ArcPy**模塊,對大量柵格遙感影像文件**批量**進行**無效值**(**NoData**值)填充的方法。 在處理柵格圖像文件時,我們經常會遇到圖像中存在有無效值(即**NoData**值)的情況。如下圖所示,這裡有一個**矢量面要素圖層**和該矢量圖層範圍 ...
  • 我們在初學 Java 編程的時候,總是感覺很枯燥乏味,想著做點可以交互的小系統,可以讓用戶自由輸入,系統可以接收做出反映。這就要介紹一下 Java 中的 Scanner 類了。 ...
  • 通過python來開發web應用,可以產簡化了web開發的流程,功能和函數庫也是非常豐富,我們也是開箱即用,目前比較流程的WEB框架就是Flask和django。 > 根據2020年JetBrains Python開發人員調查,Django和Flask是迄今為止最受歡迎的兩個Python Web框架 ...
  • 在今年2月14日的時候,Keycloak 團隊宣佈他們正在棄用大多數 Keycloak 適配器。其中包括Spring Security和Spring Boot的適配器,這意味著今後Keycloak團隊將不再提供針對Spring Security和Spring Boot的集成方案。但是,如此強大的Ke ...
  • # 1.初識列表(list) **列表由一系列按特定順序排列的數據元素組成**。可以將任何類型數據元素加入列表中,其中的數據元素之間沒有任何關係。鑒於列表通常包含多個數據元素,給列表指定一個表示覆數的名稱是個不錯的選擇。 在python中,用方括弧[]來表示列表,並用逗號來分隔其中的數據元素。編寫程 ...
  • # 出錯信息 ``` 我使用flask時,運行後出現下麵的錯誤:Traceback (most recent call last): File "D:/github/lind-python/test-web.py", line 1, in from flask import Flask File " ...
  • ## 引言 之前說的做自動記錄 Todo 執行過程中消耗的時間的[Todo 項目]( https://github.com/circler3/TodoTrack ),由於想持續保持程式執行,就放棄了 `Spectre.Console.Cli`,後來隨著命令越來越多,自己處理覺得很是麻煩,想了想要不試 ...
  • 經常坐地鐵,卻不知道地鐵多少條線路?哪個站下車?今天就帶領大家熟悉並繪製深圳地鐵路線圖。 WPF在繪製矢量圖方面有非常強大的優勢,利用WPF可以繪製出各種矢量圖形,如線,圓,多邊形,矩形,及組合圖形。今天以繪製深圳地鐵路線圖為例,簡述WPF在圖形繪製方面的一些知識,僅供學習分享使用,如有不足之處,還 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...