JAVAEE之文件IO_數據流概念,字節流:InputStream、OutputStream,字符流:reader、writer,及實例代碼

什么是數據流

?顧名思義,I 表示input,O 表示output,也就是輸入輸出流,主要是在程序與文件之間,用于傳輸數據的通道。既然要傳輸數據,那么我們需要理解文件和程序之間哪種方向的傳輸是輸入流,哪種傳輸作為輸出流?我們可以舉一個例子,如下圖所示:
在這里插入圖片描述
?IO 流是 Java IO 中的核心概念。流是在概念上表示無窮無盡的數據流。IO 流連接到數據源或數據的目的地,連接到數據源的叫輸入流,連接到數據目的地的叫輸出流。Java 程序不能直接從數據源讀取和向數據源寫入,只能借助 IO 流從輸入流中讀取數據,向輸出流中寫入數據。
?Java IO 中的流可以是基于字節的(讀取和寫入字節)也可以基于字符的(讀取和寫入字符),所以分為字節流和字符流,兩類流根據流的方向都可以再細分出輸入流和輸出流。
注意:這里的輸入、輸出是站在CPU的角度。


一、字節流

?字節流主要操作字節數據或二進制對象。字節流有兩個核心抽象類:InputStream 和 OutputStream。所有的字節流類都繼承自這兩個抽象類。

1.1 輸入字節流:InputStream

?InputStream 只是一個抽象類,要使用還需要具體的實現類。關于 InputStream 的實現類有很多,基本可以認為不同的輸入設備都可以對應一個 InputStream 類,我們現在只關心從文件中讀取,所以使用 FileInputStream
常用的方法
在這里插入圖片描述
參考實例代碼:

package CharStream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class Demo3 {public static void main(String[] args) {//1、創建File對象try(InputStream inputStream = new FileInputStream("D:/text.txt")){byte[] buffer = new byte[1024];int n = inputStream.read(buffer);   //2、讀取文件內容System.out.println("n:"+n);for (int i = 0; i < n; i++) {System.out.printf("%x\n",buffer[i]);}} catch (IOException e) {throw new RuntimeException(e);}}
}

利用 Scanner 進行字符讀取

?我們看到了對字符類型直接使用 InputStream 進行讀取是非常麻煩且困難的,所以,我們使用一種我們之前比較熟悉的類來完成該工作,就是 Scanner 類。

package CharStream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;public class Demo5 {public static void main(String[] args) {try(InputStream inputStream = new FileInputStream("d:/text.txt")){//此時scanner就是從文件中讀取了!!Scanner scanner = new Scanner(inputStream);String s = scanner.next();System.out.println(s);} catch (IOException e) {throw new RuntimeException(e);}}
}

1.2 輸出字節流:OutputStream

構造方法:
在這里插入圖片描述
?OutputStream 同樣只是一個抽象類,要使用還需要具體的實現類。我們現在還是只關心寫入文件中,所以使用 FileOutputStream。
常用方法
在這里插入圖片描述
參考實例代碼:

package CharStream;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class Demo4 {public static void main(String[] args) {//1. 打開文件,如果文件存在,會清除文件的內容,如果文件不存在,就會創建新文件try(OutputStream outputStream  = new FileOutputStream("d:/text.txt",true)){String s= "你好世界";//2. 使用wirte方法寫入內容,字符串調用getBytes()方法可以得到字符串對應的字節數組outputStream.write(s.getBytes());    //和writer類似,OutPutStream打開一個文件,就會默認清空文件的原有內容,如果不想清空,在構造方法中第二個參數傳入true//3. 關閉文件} catch (IOException e) {throw new RuntimeException(e);}}
}

?上述,我們其實已經完成輸出工作,但總是有所不方便,我們接來下將 OutputStream 處理下,使用PrintWriter 類來完成輸出,因為PrintWriter 類中提供了我們熟悉的 print/println/printf 方法。
參考實例代碼如下:

package CharStream;import java.io.*;
public class Demo6 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("d:/text.txt")){//這里就相當于把字節流轉成字符流了PrintWriter writer = new PrintWriter(outputStream);writer.println("hello");writer.flush();   //} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}

二、 字符流

?上面的字節流是以字節為單位讀寫文件數據,但是對unicode字符來說,中文字符占了兩個字節,處理不當會出現“亂碼”現象。
?字符流操作的是字符,字符流有兩個核心類:Reader 類和 Writer 。所有的字符流類都繼承自這兩個抽象類。

2.1 輸入字符流: Reader

字符流輸入流作用:讀取文件內容。
參考實例代碼:

package CharStream;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;public class Demo1 {/*** 字符流* read* @param args* @throws IOException*/public static void main(String[] args) throws IOException {//  Reader reader = new FileReader("d:/text.txt");/*** 1.一次read一個字符** while(true){*             int c  = reader.read();   //無參數read,一次只返回一個字符*             if (c== -1){*                 //讀取完畢*                 break;*             }*             char ch = (char) c;*             System.out.println(ch);*         }*/try{//2.一次read多個字符while(true){char[] cubf = new char[1024];int n = reader.read(cubf);* n表示當前讀取到的字符的個數*  一個參數read:一次讀取若干個字符,會把參數指定的cbuf數組給填充滿*  應該往這個read里傳入的是一個空的字符數組,然后由read方法內部對這個數組內容進行填充,次數"cbhf"這個參數,稱為”輸出型參數·“if (n== -1){//完畢讀取break;}System.out.println("n = "+n);for (int i = 0; i < n; i++) {System.out.println(cubf[i]);}}}finally {reader.close();//3. 一個文件使用完了,要記得close (使用close方法,最主要的方法是為了釋放文件描述符)}*///try with resources語法的目的 :()定義的變量,會在try代碼快結束的時候(無論是正常結束還是拋異常),自動調用其中的close方法try(Reader reader = new FileReader("D:/text.txt") ){while(true){char[] cubf = new char[3];int n = reader.read(cubf);if (n == -1){break;}System.out.println("n:"+n);for (int i = 0; i < n; i++) {System.out.println(cubf[i]);}}}// reader.read();   //三個參數read:一次讀取若干個字符,會把參數執行的cbuf數組中的off這個位置開始,到len這么長的范圍內填滿}
}

2.2 輸出字符流:Writer

參考代碼實例:

package CharStream;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;/*** @author Zhang* @date 2024/5/1620:23* @Description:*/
public class Demo2 {/***字符流* write* @param args*/public static void main(String[] args) {try(Writer writer = new FileWriter("d:/text.txt",true);) {writer.write("我在學習IO");  //寫入文件,默認會把原來的內容清空,解決辦法加true} catch (IOException e) {throw new RuntimeException(e);}}
}

三、 字節流、字符流怎么選擇?

?字節流和字符流都有 read()、write()、flush()、close() 這樣的方法,這決定了它們的操作方式近似。
?字節流的數據是字節(二進制對象)。主要核心類是 InputStream 類和 OutputStream 類。字符流的數據是字符,主要核心類是 Reader 類和 Writer 類。所有的文件在硬盤或傳輸時都是以字節方式保存的,例如圖片,影音文件等都是按字節方式存儲的。字符流無法讀寫這些文件。
?所以,除了純文本數據文件使用字符流以外,其他文件類型都應該使用字節流方式。字節流到字符流的轉換可以使用 InputStreamReader 和 OutputStreamWriter。使用 InputStreamReader 可以將輸入字節流轉化為輸入字符流,使用OutputStreamWriter可以將輸出字節流轉化為輸出字符流。

相關練習:掃描指定目錄,并找到名稱中包含指定字符的所有普通文件(不包含目錄),并且后續詢問用戶是否要刪除該文件:

package CharStream;import java.io.File;
import java.util.Scanner;/*** @author Zhang* @date 2024/5/1715:28* @Description:*/
public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 1. 先讓用戶輸入一個要掃描的目錄System.out.println("請輸入要掃描的路徑");String path = scanner.next();//判斷路徑是否存在File rootPath = new File(path);if (!rootPath.isDirectory()){System.out.println("您輸入的掃描的路徑有誤");return;}//2.再讓用戶輸入一個要查詢的關鍵詞System.out.println("請輸入要刪除文件的關鍵詞");String word = scanner.next();//3. 進行遞歸掃描,這個方法進行遞歸scanDir(rootPath,word);}private static void scanDir(File rootPath, String word) {//1. 先列出rootPath 中的所有文件和目錄File[] files = rootPath.listFiles();if(files  == null){///當前目錄為空,就可以直接返回了return;}//2. 遍歷這里的每個元素,針對不同各類型做出不同的處理for (File f: files){System.out.println("當前掃描的文件:"+f.getAbsolutePath()); //加個日志,方便觀察當前遞歸的執行過程if (f.isFile()){//普通文件,檢查是否要被刪除,并執行刪除操作checkDelete(f,word);}else {//目錄,運用遞歸再去判定子目錄里包含的內容scanDir(f,word);}}}private static void checkDelete(File f, String word) {if (!f.getName().contains(word)){//不必刪除,直接方法結束return;}//需要刪除System.out.println("當前文件為:"+f.getAbsolutePath() +",確認是否要刪除");Scanner scanner  = new Scanner(System.in);String choice = scanner.next();if (choice.equals("Y") || choice.equals("y")){//真正執行刪除操作f.delete();System.out.println("刪除完畢!");}else{//如果出入其他值,不一定是n,都會取消刪除操作System.out.println("取消操作!");}}
}

總結

文件IO流框架:
在這里插入圖片描述

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

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

相關文章

SD-WAN供應商的類型及選擇指南

在企業加速數字化轉型的背景下&#xff0c;SD-WAN技術成為優化網絡性能和提升連接效率的重要方案&#xff0c;受到了廣泛關注。本文將介紹當前主要的SD-WAN供應商類型及其特點&#xff0c;并提供企業選擇合適供應商的建議。 目前&#xff0c;市場上的SD-WAN供應商主要分為兩類&…

操作系統(3) 處理機調度

目錄 一、處理機調度概述 1.基本準則 &#xff08;1&#xff09;CPU利用率 &#xff08;2&#xff09;系統吞吐量 &#xff08;3&#xff09;周轉時間 &#xff08;4&#xff09;等待時間 &#xff08;5&#xff09;響應時間 2.進程調度方式 &#xff08;1&#xff0…

現代密碼學-數字簽名

從消息認證碼到數字簽名 前面講到&#xff0c;消息認證碼無法防止否認&#xff0c;A,B之間共享密鑰計算出MAC,A,B都能計算出MAC,對于第三方C來說&#xff0c;他無法證明這個MAC是A計算的還是B計算的。 通過數字簽名解決問題。 A,B各自使用不同的密鑰-公鑰密碼&#xff0c;A用…

LeetCode刷題之HOT100之組合總和

2024/6/3 周一&#xff0c;工作日的第一天。昨晚夢到被導師說去實驗室不積極哈哈哈&#xff0c;風扇開到二級&#xff0c;早上被吹醒。買的書馬上快要到了。上午剛來準備刷題&#xff0c;結果去搞了一下數據庫sql&#xff0c;做的差不多了&#xff0c;還差點格式轉換就差不多出…

springboot打包筆記

文章目錄 多配置文件application.yml本地啟動參數替換profiles&#xff0c;還是要復制文件 項目有各種環境&#xff0c;例如&#xff1a;local&#xff0c;uat&#xff0c;prd等。 各種打包方式一定要熟練掌握。 做此筆記是因為做了那么多項目&#xff0c;也打了很多包&#xf…

QT中如何對引入的第三方庫進行翻譯

1、背景 在我們的程序中,可能會加載其他人寫的模塊,,該模塊是以庫的形式提供的,那么我們程序翻譯時,如何來對引入的第三方庫進行翻譯??? 2、方案 首先,第三方庫會有自己的翻譯文件,并且一般要給我們提供設置翻譯的接口, 例如下:第三方庫給我們暴露一個接口,我們…

軍用電源性能測試有哪些測試項目?需要遵循什么標準?

為了確保軍用電源在極端條件下能夠正常工作&#xff0c;必須對其進行一系列嚴格的性能測試。這些測試不僅包括效率、電壓調整率和負載調整率等基本參數的測試&#xff0c;還包括動態響應能力、絕緣電阻、耐壓測試、溫度系數以及高低溫循環等綜合性能的評估。 測試項目 效率 電壓…

spring 優雅替換bean

方案一&#xff1a;使用 Primary/Qualifier 注解&#xff08;優選&#xff09; 如果有多個相同類型的 Bean 存在&#xff0c;可以將想要優先使用的 Bean 加上 Primary 注解。 Qualifier和Primary注解的區別&#xff1a;Primary注解用于標記具有相同類型的多個實例中的主要實例…

MySQL -- 連接查詢

MySQL使用連接查詢&#xff08;JOIN&#xff09;是為了從多個相關表中獲取數據。連接查詢是一種強大且常用的操作&#xff0c;可以根據某些條件將兩張或多張表中的數據組合在一起&#xff0c;返回一個聯合結果集。 1.為什么使用連接查詢 數據規范化&#xff1a; 數據庫設計時通…

站點被篡改快照被劫持解決服務方法教程_一招制敵

站點被篡改快照被劫持解決服務方法教程_一招制敵 被篡改表現形式&#xff1a; 站點打不開或跳轉到別的網站。 攻擊者目的&#xff1a; 報復、勒索、賣防御產品&#xff08;如DDOS防御產品&#xff09;。 攻擊成本&#xff1a; 工具&#xff08;如VPN購買&#xff09;成本、人…

智能工廠生產設備實時監控技術的UI設計

智能工廠生產設備實時監控技術的UI設計

Flutter的Dart語法入門

文章目錄 前言1. 類型聲明2. 數據類型2.1 基本數據類型常量 2.2 String2.3 集合2.4 unicode 3. Dart函數特征3.1 可變參數列表和默認入參3.2 匿名函數3.3 typedef 4. Dart面向對象4.1 構造函數4.2 訪問權限4.3 類的繼承 參考資料附錄 前言 每個語言都有控制流語句就不寫測試代…

Go 語言的控制結構:條件與循環

Go 語言提供了豐富的控制結構&#xff0c;使得開發者可以編寫出具有復雜邏輯的程序。這些控制結構包括用于條件分支的 if-else 和 switch 語句&#xff0c;循環控制的 for 語句&#xff0c;以及用于控制循環執行流的 break 和 continue 關鍵字。此外&#xff0c;Go 語言還支持 …

約瑟夫游戲(編號+密碼)

編號為1、2、3、...、N的N個人按順時針方向圍坐一圈&#xff0c;每人持有一個密碼&#xff08;正整數&#xff09;。從指定編號為1的人開始&#xff0c;他的密碼為M的初始值&#xff0c;按順時針方向從1號自己開始順序報數&#xff0c;報到指定數M時停止報數&#xff0c;報M的人…

i18n-demo

一、demo 1、資源文件準備 resources下放各個語言文件&#xff0c;直接放resources下都行。我新建一個文件夾&#xff0c;

房地產vr全景展示交互視頻讓購房者更有參與感

在當今房地產市場中&#xff0c;購房者的需求日益多樣化和個性化。為滿足這一趨勢&#xff0c;我們創新性地將VR虛擬現實技術應用于樓盤宣傳&#xff0c;為購房者帶來前所未有的沉浸式購房體驗。 一、地理位置全景展示 通過實景拍攝與VR技術的結合&#xff0c;我們為購房者呈現…

day26-單元測試

1. 單元測試Junit 1.1 什么是單元測試&#xff1f;&#xff08;掌握&#xff09; 1.2 Junit的特點&#xff1f;&#xff08;掌握&#xff09; 1.3 基本用法&#xff1a;&#xff08;掌握&#xff09; 實際開發中單元測試的使用方式&#xff08;掌握&#xff09; public class …

C語言,排序

前言 排序&#xff0c;可以說是數據結構中必不可缺的一環。我們創造數據存儲它&#xff0c;要想知道數據之間的聯系&#xff0c;比較是必不可少的。不然&#xff0c;費勁心思得來的數據若是不能有更多的意義&#xff0c;那么拿到了又有什么用&#xff1f; 排序是計算機內經常進…

風險投資公司正在幫助小投資者購買Anthropic、OpenAI等熱門公司的股票

近年來&#xff0c;風險投資公司對于人工智能&#xff08;AI&#xff09;領域的公司&#xff0c;如Anthropic、Groq、OpenAI等&#xff0c;表現出了極高的投資熱情。這些公司因為它們在AI技術方面的創新而備受矚目。但是&#xff0c;對于很多小投資者來說&#xff0c;由于資金有…

[C#]使用C#部署yolov8的目標檢測tensorrt模型

【測試通過環境】 win10 x64 vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super 版本和上述環境版本不一樣的需要重新編譯TensorRtExtern.dll&#xff0c;TensorRtExtern源碼地址&#xff1a;TensorRT-CShar…