Java學習之——“IO流“的進階流之轉換流的學習

????????在博主的上一篇博文中,詳細的介紹了“IO”流中最基本的一些知識,包括基本的常見的字節流和字符流,以及對應的緩沖流,對于“IO”流基礎知識相對薄弱的同學可以先去看博主的上一篇博文Java學習之——萬字詳解“IO流”中基本的字節流和字符流?后在回頭來看這篇進階文章效果會更好。

????????Java IO流中的“進階”流:轉換流、序列化流、打印流和壓縮流。它們構建在基礎字節流和字符流之上,提供了更強大、更便捷的功能。

一、轉換流

1.核心概念:為什么需要轉換流?

要理解轉換流,首先要明白 Java I/O 流體系中的兩個核心分支:

  • 字節流:以字節(8 bit)為基本單位,處理所有類型的數據(如圖片、視頻、音頻等二進制文件,也包括文本文件)。基類是?InputStream?和?OutputStream
  • 字符流:以字符(16 bit,一個char)為基本單位,專門為方便處理文本數據而設計。它底層仍然是字節操作,但會自動處理字符編碼。基類是?Reader?和?Writer

問題:我們經常遇到這樣的場景——一個字節流(例如,來自網絡、文件的?FileInputStream?或?Socket.getInputStream())傳輸的是文本內容。如果我們直接使用字節流讀取,得到的是一個個字節,我們需要自己將這些字節按照正確的字符編碼(如 UTF-8, GBK)拼接和轉換成字符,非常麻煩且容易出錯。

解決方案:轉換流(InputStreamReader?/?OutputStreamWriter)。

它們的作用就是作為一座“橋梁”,將底層的字節流?轉換為頂層的字符流,并在轉換過程中完成字節到字符的編碼解碼工作

  • InputStreamReader: 將一個字節輸入流(InputStream轉換為一個字符輸入流(Reader)。【解碼:字節 -> 字符】
  • OutputStreamWriter: 將一個字符輸出流(Writer轉換為一個字節輸出流(OutputStream)。【編碼:字符 -> 字節】

2.InputStreamReader 詳解

核心功能:InputStreamReader是?Reader的子類。它包裹著一個字節輸入流(InputStream),并讀取字節,然后使用指定的或默認的字符集將其解碼為字符。

關鍵構造函數:

// 使用默認字符集創建一個 InputStreamReader
InputStreamReader(InputStream in)// 使用指定的字符集名稱創建一個 InputStreamReader
// 字符集如:"UTF-8", "GBK", "ISO-8859-1"
InputStreamReader(InputStream in, String charsetName)// 使用指定的 Charset 對象創建一個 InputStreamReader
InputStreamReader(InputStream in, Charset cs)

工作原理:

當你調用?InputStreamReader?的?read()?方法時,會發生以下步驟:

  1. 它從內部的?InputStream?中讀取一個或多個字節。
  2. 這些字節根據構造時指定的字符集(Charset)進行解碼。
  3. 將解碼后的結果以一個?char(或多個?char?放入數組)的形式返回。

代碼示例:

????????假設我們有一個文本文件 text.txt,其編碼是 GBK。如果我們用默認字符集(通常是 UTF-8)的 FileReader(它是 InputStreamReader 的子類)讀取,可能會亂碼。使用 InputStreamReader 指定編碼可以完美解決。

import java.io.*;public class InputStreamReaderDemo {public static void main(String[] args) {try (// 1. 創建一個字節流 FileInputStreamFileInputStream fis = new FileInputStream("text.txt");// 2. 創建一個轉換流 InputStreamReader,并指定編碼為 GBKInputStreamReader isr = new InputStreamReader(fis, "GBK");// 3. 為了高效,通常用 BufferedReader 包裹 InputStreamReaderBufferedReader br = new BufferedReader(isr)) {String line;// 此時讀取到的字符已經是正確解碼后的文本,不會亂碼while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}

3.OutputStreamWriter 詳解

????????OutputStreamWriter 是 Writer 的子類。它接收字符,然后使用指定的或默認的字符集將其編碼為字節,并寫入到底層的字節輸出流(OutputStream)中。

關鍵構造函數

// 使用默認字符集創建一個 OutputStreamWriter
OutputStreamWriter(OutputStream out)// 使用指定的字符集名稱創建一個 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)// 使用指定的 Charset 對象創建一個 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)

工作原理

當你調用?OutputStreamWriter?的?write()?方法時,會發生以下步驟:

  1. 你傳入的字符(或字符串)根據構造時指定的字符集(Charset)進行編碼。
  2. 編碼后得到的一個或多個字節被寫入到底層的?OutputStream?中。
  3. OutputStream?最終將這些字節寫入到目標(文件、網絡等)。

我們想要將一個字符串以?GBK?編碼寫入到文件中。

import java.io.*;public class OutputStreamWriterDemo {public static void main(String[] args) {try (// 1. 創建一個字節流 FileOutputStreamFileOutputStream fos = new FileOutputStream("output.txt");// 2. 創建一個轉換流 OutputStreamWriter,并指定編碼為 GBKOutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");// 3. 為了高效和方便,通常用 BufferedWriter 包裹BufferedWriter bw = new BufferedWriter(osw)) {String content = "你好,世界!";bw.write(content);bw.newLine();bw.write("This is a test.");} catch (IOException e) {e.printStackTrace();}// 最終文件 output.txt 的編碼將是 GBK}
}

與 FileReader / FileWriter 的關系

  • FileReader?本質上是?InputStreamReader?的子類,它簡化了文件的讀取,但無法指定編碼,只能使用默認編碼。FileWriter?同理。

  • 結論:在需要明確指定編碼的場合(絕大多數國際化和跨平臺場景),不要直接使用?FileReader?和?FileWriter,而應該使用?InputStreamReader?和?OutputStreamWriter?并手動指定編碼。FileReader/FileWriter?僅適用于處理與系統默認編碼一致的文件。

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

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

相關文章

PMP考試結構、學習框架與基本術語

一、PMP考試整體結構 考試基本信息 考試形式:紙筆考試(中國大陸地區)考試時長:230分鐘(約4小時)題目數量:180道題 170道單選題(四選一)10道多選題包含5道非計分的試驗題…

淺談前端框架

在 Web 開發的演進過程中,前端框架扮演著越來越重要的角色。從早期的 jQuery 到如今的 React、Vue、Svelte 等,前端開發模式發生了翻天覆地的變化。本文將從前端框架的定義、核心特性、分類以及主流框架的差異等方面,帶你深入理解前端框架。 …

10.3 馬爾可夫矩陣、人口和經濟

本節內容是關于正矩陣(postive matrices): 每個元素 aij>0a_{ij}>0aij?>0,它核心的結論是:最大的特征值為正實數,其對應的特征向量也是如此。 在經濟學、生態學、人口動力系統和隨機游走過程中都…

python學習進階之面向對象(二)

文章目錄 1.面向對象編程介紹 2.面向對象基本語法 3.面向對象的三大特征 4.面向對象其他語法 1.面向對象編程介紹 1.1 基本概念 概念:面向對象編程(Object-Oriented Programming, OOP)是一種流行的編程范式,它以"對象"為核心組織代碼和數據 在面向對象的世界里: …

VS+QT的編程開發工作:關于QT VS tools的使用 qt的官方幫助

加粗樣式 最近的工作用到VS2022QT5.9.9/QT5.12.9,在查找相關資料的時候,發現Qt 官方的資料還是很不錯的,特記錄下來,要記得抽時間學習下。 Add Qt versions https://doc.qt.io/qtvstools/qtvstools-how-to-add-qt-versions.html B…

【系統分析師】第21章-論文:系統分析師論文寫作要點(核心總結)

更多內容請見: 備考系統分析師-專欄介紹和目錄 文章目錄 一、寫作注意事項:構建論文的合規性與專業性 1.1 加強學習 1.2 平時積累 1.3 提高打字速度 1.4 以不變應萬變 二、試題解答方法:結構化應對策略 2.1 試題類型分析 2.2 三段式答題框架 2.3 時間分配 三、論文寫作方法:…

tailwindcss 究竟比 unocss 快多少?

tailwindcss 究竟比 unocss 快多少? 前言 大家好,我是去年一篇測評 《unocss 究竟比 tailwindcss 快多少?》 的作者 icebreaker。 一晃到了 2025 年,tailwindcss4 也正式發布了,現在最新版本是 4.1.13。 新版本不僅…

算法練習——55.跳躍游戲

1.題目描述給你一個非負整數數組 nums ,你最初位于數組的 第一個下標 。數組中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最后一個下標,如果可以,返回 true ;否則,返回 false 。示例 1&#xff…

Django 項目6:表單與認證系統

目錄 1、form 表單 2、session 保存狀態 3、Admin 后臺 4、Auth 系統 1、form 表單 (1)創建 form.py 文件,并完善 from django import forms# 定義一個表單類 class Register(forms.Form):user forms.CharField(max_length30, label用…

tvm/triton/tensorrt比較

1.tvm的主線感覺更新太慢,文檔太落后,在自動駕駛領域不支持Blackwell平臺,跨平臺其實吹牛的更多。我覺得自動駕駛用不起來。2.性能最快的還是tensorrt/tensorrt_llm這條路,純cuda路線面臨大量cuda算子開發,比如vllm ll…

Transform 和BERT、GPT 模型

目錄 Transform的由來 Seq2seq 模型 Transform 的內部結構 語言模型 BERT 介紹 BERT 模型的組成 分詞器 位置編碼 Softmax 殘差結構 BERT 模型總結 Transform的由來 傳統的語?模型,?如RNN(循環神經?絡),就像?個“短…

2025高教社國賽數學建模A題參考論文35頁(含代碼和模型)

2025國賽數學建模競賽A題完整參考論文 目錄 摘要 1 問題背景與重述 2 問題分析 2.1 問題一分析 2.2 問題二分析 2.3 問題三分析 2.4 問題四分析 2.5 問題五分析 3 符號說明 4 模型假設 5 模型建立與求解 5.1 問題一 煙幕有效遮蔽時長…

【Linux】常用命令匯總

【Linux】常用命令【一】tar命令【1】可用參數【2】常用案例(1)創建歸檔(打包)(2)查看歸檔內容:??(3)解包歸檔 (提取):??【二】日志查看命令【1】基礎命令…

軟考系統架構設計師之軟件系統建模

一、軟件系統建模 系統建模流程包括如下: 二、人機交互設計 黃金三法則: 1、置于用戶控制之下以不強迫用戶進入不必要的或不希望的動作的方式來定義交互方式 提供靈活的交互 允許用戶交互可以被中斷和撤銷 當技能級別增加時可以使交互流水化并允許定制交…

Linux系統學習之注意事項及命令基本格式

哈嘍,你好啊,我是雷工!你要是翻過歷史文章的話,肯定特別疑惑:這神經病搞得這個號到底是啥定位,究竟是分享啥類型的,咋亂七八糟的啥都有。真是個雜貨鋪啥都有,咋又開始分享Linux系統了…

0基礎Java學習過程記錄——枚舉、注解

一、枚舉1.基本介紹(1)枚舉對應英文 enumeration,簡寫為 enum(2)枚舉是一組常量的集合(3)可以理解為:枚舉屬于一種特殊的類,里面只包含一組有限的特定的對象2.實現方式&a…

高效計算的源泉:深入淺出馮諾依曼模型與操作系統的管理藝術 —— 構建穩定、高效的應用基石 【底層邏輯/性能優化】

???~~~~~~歡迎光臨知星小度博客空間~~~~~~??? ???零星地變得優秀~也能拼湊出星河~??? ???我們一起努力成為更好的自己~??? ???如果這一篇博客對你有幫助~別忘了點贊分享哦~??? ???如果有什么問題可以評論區留言或者私信我哦~??? ??????個人…

性能測試-jmeter9-邏輯控制器、定時器壓力并發

課程:B站大學 記錄軟件測試-性能測試學習歷程、掌握前端性能測試、后端性能測試、服務端性能測試的你才是一個專業的軟件測試工程師 性能測試-jmeter邏輯控制器、定時器妙用IF控制器**IF 控制器的作用**循環控制器循環控制器的作用ForEach控制器ForEach 控制器的作用…

T:線段樹入門(無區間更新)

線段樹.線段樹介紹.線段樹框架.理解線段樹.圖式整個過程.線段樹代碼逐層解析.代碼匯總.leetcode練習.線段樹介紹 線段樹(SegmentTree)\;\;\;\;\;\;\;\;線段樹(SegmentTree)線段樹(SegmentTree) is 用于高效處理區間查詢和單點修改的數據結構,和樹狀數組很像&#xf…

【ISP】Charlite工具實操

實習一周了&#xff0c;參與了客觀拍攝和測試&#xff0c;復習一下nv工具 BLACK LEVEL&#xff08;黑電平&#xff09; eg&#xff1a; $ nv_ob 0 in_dir <input directory> out_name <ob file> nv_ob 0 in_dir D:\study\nvraw\ob1 out_name D:\study\nvraw\my_out…