字節流與字符流的區別

最近在項目中遇到一個encoding的問題,記錄一下。

??? 具體而言就是,項目中有A/B兩個部分,A部分由我們負責,Java實現;B部分是UK負責的,使用Delphi,A、B在交互時發送一個http請求, 請求匯總包括一些文本信息(header),以及一個zip文件(body)。好了,問題出來了,當我們發送請求過去時,B能接收到請求,并讀出 header,也能讀出body部分的zip文件,但是讀出的zip文件確實corrupted,死活不能打開。

???? --------------------

? ?? ---header(文本)-

???? -----body(zip)---

???? --------------------

?? 經過無數反復的折騰后(與UK的人同步,痛苦啊),發現我們的系統有問題,問題是在于,我們在構造請求文件的時候,是把zip文件作為一個字符流讀取,并 添加到一個字符流中,然后把這個字符流發送出去。這個body部分,加入到body后,就成為字符流的一部分,結果也帶有encoding信息,這樣發送 到B部分后,就無法正確讀取了。

?? ?? ------------------------

? ??? ---header(String)---

A??? -------------------------? ? ? ? ? ? ?? ------>? httpClient)(String)? ------------->B

????? -----body(String)----

????? -------------------------

?? 正確的做法應該是,在讀取header部分后,轉化為字節流存入一個暫時的byte pool中,然后再把zip部分也作為一個字節流讀出,放到上面的byte pool中。最后把這個byte pool 發送 出去。

?

???? ------------------------

? ?? ---header(string)---

? A -------------------------? ? ? ? ? ? ?? ------>? httpClient)(byte[])? ------------->B

???? -----body(byte[])----

???? -------------------------

?

? 從這個例子可以更加深刻的認識下面的道理:

? 概念:

??? 字符流處理的單元為2個字節的Unicode字符,分別操作字符、字符數組或字符串,而字節流處理單元為1個字節, 操作字節和字節數組。所以字符流是由Java虛擬機將字節轉化為2個字節的Unicode字符為單位的字符而成的,所以它對多國語言支持性比較好!如果是 音頻文件、圖片、歌曲,就用字節流好點,如果是關系到中文(文本)的,用字符流好點.
???? 所有文件的儲存是都是字節(byte)的儲存,在磁盤上保留的并不是文件的字符而是先把字符編碼成字節,再儲存這些字節到磁盤。在讀取文件(特別是文本文件)時,也是一個字節一個字節地讀取以形成字節序列.
????? 字節流可用于任何類型的對象,包括二進制對象,而字符流只能處理字符或者字符串; 2. 字節流提供了處理任何類型的IO操作的功能,但它不能直接處理Unicode字符,而字符流就可以。

? 轉換:

在從字節流轉化為字符流時,實際上就是byte[]轉化為String時,
public String(byte bytes[], String charsetName)
有一個關鍵的參數字符集編碼,通常我們都省略了,那系統就用操作系統的lang
而在字符流轉化為字節流時,實際上是String轉化為byte[]時,
byte[]????String.getBytes(String charsetName)
也是一樣的道理

? Java操作篇:

? IO分兩種流

字節流 InputStream OutputStream

字符流 Reader Writer

他們都是抽象類

具體實現
字節流 FileInputStream FileOutputStream
字符流 FileReader FileWriter?

? 字節流轉換成字符流可以用 InputSteamReader OutputStreamWriter

轉換成BufferdReader BufferedWriter 他們具有緩沖區

例如:讀取文件 從字節流輸入到字符流輸入
定義一個字節流:
FileInputStream fileInputStream = new FileInputStream("d:/text.txt");

// 定義一個指向D:/TEXT.TXT 的字節流

InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
//字節流轉換成InputStreamReader
BufferedReader bufferedReader = new BufferedReader(inputSteamReader);
//InputStreamReader 轉換成帶緩存的bufferedReader

可以把讀出來的內容賦值給字符

String ss = new String();
String s;
while((s = bufferedReader.readLine())!=null){
ss += s;
}

例如:寫入文件 從字節流輸出到字符流輸出

FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt"); //定義一個

指向D:/TEXT.TXT文件

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);

BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);

bufferedWriter.write(s);

bufferedWriter.close();
outputStreamWriter.close();
fileOutputStream.close();


例程:
???? 將字符串轉化為字節流#region 將字符串轉化為字節流
??????? /** <summary>
??????? /// 將字符串轉化為字節流
??????? /// </summary>
??????? /// <param name="_Source">字串</param>
??????? /// <returns>字節流</returns>
??????? public static byte[] String2Bytes(string strSource)
??????? {
??????????? System.IO.MemoryStream?? memoryStream=new?? System.IO.MemoryStream();??
??????????? System.IO.BinaryWriter?? binaryWriter=new?? System.IO.BinaryWriter(memoryStream);??
??????????? binaryWriter.Write( strSource );
??????????? byte[]?? buffer=memoryStream.GetBuffer();
??????????? return buffer;???
??????? }
??????? #endregion

???????
??????? 將字節流轉化為字符串#region 將字節流轉化為字符串
??????? /** <summary>
??????? /// 將字節流轉化為字符串
??????? /// </summary>
??????? /// <param name="bytData">字節流</param>
??????? /// <returns>字串</returns>
??????? public static string Bytes2String(byte[] bytData)
??????? {
??????????? //字節流->字符串??
??????????? System.IO.MemoryStream?? memoryStream2 = new?? System.IO.MemoryStream(bytData);??
??????????? System.IO.BinaryReader?? binaryReader = new?? System.IO.BinaryReader(memoryStream2);??
??????????? string?? s2=binaryReader.ReadString();??
??????????? return s2;
??????? }
??????? #endregion

?

轉載于:https://www.cnblogs.com/toSeeMyDream/p/5599817.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374489.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374489.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374489.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通過MOXy實現使JAXB更加清潔

編組和解組XML時使用JAXB的主要優點是編程模型。 只需注釋幾個POJO并使用JAXB API&#xff0c;您就可以很容易地序列化為XML和從XML反序列化。 您無需擔心有關XML如何編組/解組的細節。 一切都比DOM和SAX等替代方案簡單得多。 現在&#xff0c;XML文件中的數據本質上趨于分層。…

android 上下滾動文字_計算機畢設項目004之Android系統在線小說閱讀器

計算機畢設項目004之Android系統在線小說閱讀器一. 項目名稱基于Android系統的在線小說閱讀器二. 項目簡介項目中的角色功能&#xff1a;支持翻頁動畫:仿真翻頁、覆蓋翻頁、上下滾動翻頁等翻頁效果。支持頁面定制:亮度調節、背景調節、字體大小調節支持全屏模式(含有虛擬按鍵的…

697. 數組的度

給定一個非空且只包含非負數的整數數組 nums&#xff0c;數組的 度 的定義是指數組里任一元素出現頻數的最大值。 你的任務是在 nums 中找到與 nums 擁有相同大小的度的最短連續子數組&#xff0c;返回其長度。 來源&#xff1a;力扣&#xff08;LeetCode&#xff09; 鏈接&a…

python math模塊

1.math簡介 >>> import math >>>dir(math) #這句可查看所有函數名列表 [__doc__, __name__, __package__, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, copysign, cos, cosh, degrees, e, erf, erfc, exp, expm1, fabs, factorial, flo…

Visual Studio找不到adb.exe錯誤解決

Visual Studio找不到adb.exe錯誤解決 錯誤信息&#xff1a;Cannot find adb.exe in specified SDK path。出現這種情況&#xff0c;是因為沒有安裝Android SDK Platform-tools。解決辦法&#xff1a;在SDK Manager中&#xff0c;安裝該組件即可。 轉載于:https://www.cnblogs.c…

Vaadin應用程序中的EJB查找

自從我實現上一個服務定位器以來已經有很長時間了。 我認為不再需要考慮Java EE CDI &#xff08;上下文和依賴注入&#xff09;的成熟度。 我的第一個實現是在基于Struts的Web應用程序中使用EJB。 之后&#xff0c;我開始使用JSF&#xff0c;它只需要帶有EJB或Resource的帶注釋…

基線檢查工具_最新版CAD燕秀工具箱2.87(支持20042021)

好課推薦&#xff1a;零基礎CAD&#xff1a;點我CAD家裝&#xff1a;點我 周站長CAD&#xff1a;點我CAD機械&#xff1a;點我revit教程&#xff1a;點我CAD建筑&#xff1a;點我CAD三維&#xff1a;點我全屋定制&#xff1a;點我 ps教程&#xff1a;點我蘋果版CAD:點我 3dmax教…

團隊項目記錄2

遇到的問題&#xff1a;在對Trigger機關進行測試時發現&#xff0c;畫出的軌道也會將機關觸發。 問題描述&#xff1a;Trigger機關的作用是在發生碰撞時運行腳本中指定的特定物體的特定函數&#xff0c;在這個例子當中特定的物體是一塊地板&#xff0c;特定的函數的功能是刪除這…

關于java.lang.ArithmeticException

java.lang.ArithmeticException “數學運算異常”&#xff0c;可能是自己的數學運算公式出現了錯誤、違反了數學運算規則。錯誤記錄&#xff1a; 出錯原因&#xff1a; a % b 中b不能為0

1103. Integer Factorization (30)

題目如下&#xff1a; The K-P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K-P factorization of N for any positive integers N, K and P. Input Specifi…

Java EE 6與Spring Framework:技術決策過程

在過去的幾個月中&#xff0c;我們經歷了這個決策過程&#xff1a;為Java平臺上的企業開發選擇哪種技術堆棧&#xff1f; 有多種選擇。 但是&#xff0c;我們深入討論的是&#xff1a;純Java EE 6堆棧與帶有Java EE的Spring。 以下博客文章總結了當您考慮這些技術堆棧選項之一時…

DOM 基礎 HTML標簽 元素 屬性

什么是HTML標簽 HTML標簽標記了HTML文檔和HTML元素 HTML標簽由開始標簽和結束標簽組成.開始標簽為尖括號包圍的元素名,結束標簽為尖括號包圍的斜杠和元素名 例如:<h2> My First Heading</h2> HTML基本標簽 標題(Heading)是通過h1 - h6等標簽進行定義的.段落 是通過…

允許服務與桌面交互_vivo 正式推出 Origin OS,融合自然設計與全新交互

點擊右上角關注我們&#xff0c;每天給您帶來最新最潮的科技資訊&#xff0c;讓您足不出戶也知道科技圈大事&#xff01;今天下午&#xff0c;vivo 推出了全新 Origin OS 手機系統。它采用了源于自然界的設計理念&#xff0c;同時加入了全新并且允許用戶進行深度自定義的交互方…

Error - Found cycle in the ListNode

Error - Found cycle in the ListNode 刷力扣時遇到這個錯誤&#xff0c;節點成環 自己摸索了一下發現確實形成循環&#xff0c;原題是206反轉鏈表&#xff0c;我用的是棧&#xff0c;先將鏈表節點依次進棧&#xff0c;然后依次出棧鏈接&#xff0c;構成反轉。但是我忽略了第一…

JUnit 4.9(測試版3)中的規則

不久前&#xff0c; David Saff宣布了JUnit 4.9的beta版 。 因此&#xff0c;我認為現在是研究該版本中的新增功能的好時機。 JUnit領域中最有用的創新之一是Rule。 我在這里寫了有關規則的文章 。 我在這里寫了有關JUnit規則的用例 。 規則很棒。 借助JUnit 4.9&#xff0c;它…

計算機網絡-終端

我們常用的電腦來說&#xff0c;外圍設備就是終端。 外圍設備包括顯示器、鼠標、鍵盤等等。 負責向主機輸入數據的就叫輸入終端&#xff0c;比如鼠標、鍵盤、麥克風、攝像頭&#xff1b; 負責接收主機輸出數據的設備就被稱作輸出終端&#xff0c;比如顯示器、耳機。 注意一點…

為什么我喜歡Java的細節

他們說&#xff0c;Java太冗長了。 您可以找到Hello World程序的比較結果&#xff0c;這些程序在ruby中使用2行&#xff0c;在Java中使用10行&#xff0c;要讀取文件&#xff0c;您需要使用Java 20行和php中1行。 盡管示例經常被夸大&#xff08;例如&#xff0c;計算導入次數&…

dll 源碼_【技術分享】 | 一個JAVA內存馬的源碼分析

前言偶然接觸到了這樣一個JAVA內存馬&#xff0c;其作者也是冰蝎的作者&#xff0c;項目地址&#xff1a;https://github.com/rebeyond/memShell正好最近在接觸JAVA&#xff0c;借此機會學習下大佬的代碼&#xff0c;對自己的編程思路也有了一定的提升。當然筆者只是一個腳本小…

ThunderSearch(閃電搜索器)_網絡空間搜索引擎工具_信息收集

文章目錄 ThunderSearch簡介1 項目地址2 使用方式2.1 配置文件config.json說明2.2 構建和運行 3 使用式例 ThunderSearch簡介 ThunderSearch&#xff08;閃電搜索器&#xff09;是一款使用多個(【支持Fofa、Shodan、Hunter、Zoomeye、360Quake網絡空間搜索引擎】網絡空間搜索引…

字符串匹配方法

介紹兩種字符串匹配方法1.暴力匹配母串用s表示&#xff0c;長度為m子串用p表示&#xff0c;長度為n時間復雜度為:(m-n1)n算法&#xff1a;從s串的第一個字符開始匹配&#xff0c;若匹配&#xff0c;繼續根據p向后匹配&#xff0c;若后續的不匹配&#xff0c;s右移重新匹配p 2.K…