Java IO流學習指南:從小白到入門

Java的IO(Input/Output)流是處理數據輸入和輸出的基礎。無論是讀取文件、寫入文件,還是通過網絡傳輸數據,IO流都無處不在。對于剛接觸Java的新手,理解IO流可能會有些困惑,但別擔心,今天我們將一步步走過它,讓你從一個小白變成IO流的小達人!


一、什么是IO流?

在Java中,IO流是指數據流向的方向,它包括了輸入流(InputStream)和輸出流(OutputStream)兩大類。

  • 輸入流(InputStream):用于讀取數據的流,例如從文件、鍵盤或網絡中讀取數據。

  • 輸出流(OutputStream):用于向目標寫入數據的流,比如將數據寫入文件、控制臺或網絡中。

IO流的核心概念就是“數據流向”,可以理解為你從某個地方讀取數據,或者將數據寫入到某個地方。


二、IO流的分類

Java中的IO流有很多種,按用途大致可以分為兩大類:

  1. 字節流(Byte Stream):處理所有類型的I/O,適用于所有類型的數據(包括圖片、音頻、視頻等二進制數據)。字節流的父類是 InputStreamOutputStream

  2. 字符流(Character Stream):專門用于處理文本數據(即字符數據),它是對字節流的封裝,采用字符編碼方式來讀取和寫入文本數據。字符流的父類是 ReaderWriter


詳細解釋

所謂這些流就是一個鏈接文件的管道,字節,字符流,就是代表在管道里面流轉的數據不一樣輸入流就是將文件內容通過管道發送到程序。輸出流就是從程序寫入到文件里面。流的分類按照流的方向:輸入流、輸出流按照流的內容:字節流、字符流
字節流:適合操作所有類型的文件 字符流:適合操作純文本文件
他們之間組合形成了四個類
字節輸入流 FileInputStream
字符輸出流 FileOutputStream
字符輸入流 FileReader
字符輸出流 FileWriter他們都繼承兩個基類 InputStream  OutputStream他們本質就是一些對象,擁有一些操作數據的方法。
創建對象
字節輸入流為例
FileOutputStream fos = new FileOutputStream("文件路徑");
其他就是替換類名就行了。也可以利用多態寫法,換成基類
注意:絕對路徑和相對路徑的差別,在開發多人項目的時候一般使用相對路徑,就是在你的項目中的路徑。
絕對路徑就是存放在磁盤的路徑,但當你拿別人的項目的時候一旦文件存放的磁盤不一樣就會拋出異常。方法:字符和字節一樣都有方法
讀入方法,單個字節讀入int b = fos.read();int b;while((b=is.read())!=-1){System.out.print((char)b);}
這樣效率非常慢,而且不能存放漢字,因為一個漢字的字節占位不是一,
我們一般利用數組傳入,一次性傳多個byte[] buffer = new byte[5];
int len;//定義一個變量記住每次讀取了多少個字節,因為有可能都不滿數組。
while((len=is.read(buffer))!=-1){  System.out.print(new String(buffer,0,len));//解釋一下,len是每次讀取的字節數,//即從0開始,截取len個字節,轉換成字符串輸出//String  s = new String(buffer);// System.out.println(s);//這樣寫的話,每次都會將buffer中的字節全部轉換成字符串,如果源文件只有4個字節,那么就會將buffer中多余的字節轉換成亂碼        //但是無法解決亂碼問題。//解決方法,一次讀完所以的字節,只適合小文件,大文件可能會造成內存溢出//readAllBytes()//讀取文件所有字節//byte[] bytes = is.readAllBytes();//System.out.println(new String(bytes));
 文件字節輸出流 FileOutputStream作用:將數據寫入文件覆蓋管道,會覆蓋原來的數據FileOutputStream fos = new FileOutputStream("路徑");//與字節輸入流一樣,也有一個字節輸出流管道與源文件路徑接通//FileOutputStream(File file)//與源文件路徑接通(一般用)//FileOutputStream(String path)//寫數據文件會自動創建文件FileOutputStream fos = new FileOutputStream("file_io_stream\\src\\text02.txt");//同樣的文件字節輸出流也有將讀到文件里面的方法,但是和輸入流也存在亂碼問題,解決方式也一樣//一個字節寫入一個字節 write()fos.write('9');//也有數組方式byte[] bytess = {97,98,99,100};//將文字編碼成字節byte[] bytesss = "我愛中國".getBytes();fos.write(bytesss);fos.write(bytess);//也能寫一部分字節數組出去//將字節1-2寫出去//但是在寫漢字的時候依然會有亂碼問題//write(字節數組,起始位置,寫多少個字節出去)fos.write(bytesss,0,9);//但是這樣寫是將文件清空在寫的,所以不能重復寫入。//要追加添加文件,需要使用帶參數的構造方法//追加參數,追加數據FileOutputStream fos1 = new FileOutputStream("file_io_stream\\src\\text02.txt",true);//注意在這些流用完后一定要關閉流fos.close();fos1.close();

?但是我們流在使用后必須關閉,但是一定程序在流關閉之前就拋出異常,導致流沒有關閉,造成內存泄漏所以我們規定了流的寫法格式

try(){

}catch()

{

}

 try(只能放置資源對象,用完后最終會自動調用close方法FileInputStream fis=new FileInputStream(src);FileOutputStream fos=new FileOutputStream(dest,true);){byte[] buf=new byte[1024];int len;while((len=fis.read(buf))!=-1){fos.write(buf,0,len);//讀取多少字節就寫多少字節}}catch (Exception e){e.printStackTrace();}}

?字符和字節完全一樣,只是方法的名稱有些不一樣

讀入

 try( FileReader fr = new FileReader("file_io_stream\\src\\zi_fu_stream\\zi_fu_text");){char [] cbuf = new char[1024];//不建議單個字符讀入,會拖累程序int b;while((b = fr.read(cbuf)) != -1){//打印出來System.out.print(new String(cbuf,0,b));}//字符沒有全部讀入方式//拓展:文件字符輸入流每次讀多個字符,性能較好,而且讀中文沒有亂碼}catch (Exception e){e.printStackTrace();}

輸出

//五個方法//write(char c)//寫入一個字符//write(String str)//寫入一個字符串//write(char[] cbuf)//寫入一個字符數組//write(char[] cbuf,int off,int len)//寫入一個字符數組的一部分//flush()//刷新緩沖區,將數據寫入文件

?我們一般就使用字符串?

緩沖流

 認識緩沖流緩沖字節輸入流 BufferedInputStream緩沖字節輸出流BufferedOutputStream緩沖字符輸入流 BufferedReader緩沖字符輸出流 BufferedWriter

其實就是提高性能而且,在外面套了一層殼使用方法一模一樣就是換了類名

字符緩沖輸入流新增功能:按照行讀取字符
        try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {String line;while ((line = reader.readLine()) != null) {// 處理每一行}} catch (IOException e) {e.printStackTrace();}

三、簡單的字節流示例

先從一個最基礎的例子開始:用字節流讀取和寫入文件。

1. 讀取文件內容
import java.io.FileInputStream;
import java.io.IOException;
?
public class FileReaderExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("input.txt")) {int byteData;while ((byteData = fis.read()) != -1) {System.out.print((char) byteData);}} catch (IOException e) {e.printStackTrace();}}
}

解釋:

  • FileInputStream 是字節流的一個例子,用來讀取文件數據。

  • fis.read() 方法逐個字節讀取文件的內容。

  • try-with-resources 語法可以自動關閉資源,避免手動關閉。

2. 寫入文件內容
import java.io.FileOutputStream;
import java.io.IOException;
?
public class FileWriterExample {public static void main(String[] args) {try (FileOutputStream fos = new FileOutputStream("output.txt")) {String message = "Hello, Java IO!";fos.write(message.getBytes()); ?// 將字符串轉換為字節數組并寫入文件} catch (IOException e) {e.printStackTrace();}}
}

解釋:

  • FileOutputStream 用于將數據寫入文件。

  • write() 方法將字節數據寫入文件。


四、簡單的字符流示例

字符流適用于文本文件的讀取和寫入,它會自動進行字符編碼的轉換。

1. 讀取文本文件
import java.io.FileReader;
import java.io.IOException;
?
public class FileReaderExample {public static void main(String[] args) {try (FileReader fr = new FileReader("input.txt")) {int charData;while ((charData = fr.read()) != -1) {System.out.print((char) charData); ?// 輸出每個字符}} catch (IOException e) {e.printStackTrace();}}
}
2. 寫入文本文件
import java.io.FileWriter;
import java.io.IOException;
?
public class FileWriterExample {public static void main(String[] args) {try (FileWriter fw = new FileWriter("output.txt")) {String message = "Hello, Java IO with Character Streams!";fw.write(message); ?// 直接寫入字符串} catch (IOException e) {e.printStackTrace();}}
}

五、常用的IO流類和方法

  • FileInputStream/FileOutputStream:用于字節流讀寫文件。

  • FileReader/FileWriter:用于字符流讀寫文件。

  • BufferedReader/BufferedWriter:用于高效地讀取和寫入字符數據,適合處理大量文本數據。

1. 使用 BufferedReader 讀取文件
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
?
public class BufferedReaderExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line); ?// 逐行讀取文件內容}} catch (IOException e) {e.printStackTrace();}}
}
2. 使用 BufferedWriter 寫入文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
?
public class BufferedWriterExample {public static void main(String[] args) {try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {String message = "Buffered Writer Example";bw.write(message); ?// 寫入內容} catch (IOException e) {e.printStackTrace();}}
}

六、IO流的實際應用場景

  1. 讀取和寫入文件:最常見的應用,比如讀取配置文件、寫入日志文件等。

  2. 網絡通信:通過Socket連接進行網絡數據的發送和接收。

  3. 數據加密與解密:處理加密文件的讀取和寫入。

  4. 多線程并發訪問文件:使用IO流結合多線程技術,處理并發文件操作。


最后介紹一下io框架

commons-io.jar

為了簡化上面的方法,io框架將上面的內容封裝成了一個個內容,方便我們直接調用,說白了上面學了都沒用,直接用框架就行,但是我們還是要掌握數據流動的方式。

1. IOUtils

處理輸入/輸出流的工具類。

方法列表與作用
方法作用
copy(InputStream, OutputStream)復制輸入流到輸出流(自動緩沖)
toString(InputStream, Charset)將輸入流內容轉為字符串
readLines(InputStream, Charset)按行讀取輸入流為字符串列表
示例代碼
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
?
public class IOUtilsExample {public static void main(String[] args) throws IOException {// 1. 復制流try (InputStream in = new FileInputStream("input.txt");OutputStream out = new FileOutputStream("output.txt")) {IOUtils.copy(in, out); // 將 input.txt 內容復制到 output.txt}
?// 2. 輸入流轉字符串try (InputStream in = new FileInputStream("input.txt")) {String content = IOUtils.toString(in, StandardCharsets.UTF_8);System.out.println(content); // 輸出文件內容}
?// 3. 按行讀取try (InputStream in = new FileInputStream("input.txt")) {List<String> lines = IOUtils.readLines(in, StandardCharsets.UTF_8);lines.forEach(System.out::println); // 逐行打印}}
}

2. FileUtils

文件操作工具類。

方法列表與作用
方法作用
readFileToString(File, Charset)讀取文件內容為字符串
writeStringToFile(File, String, Charset)將字符串寫入文件
copyFile(File, File)復制文件
copyDirectory(File, File)復制整個目錄
deleteDirectory(File)遞歸刪除目錄
cleanDirectory(File)清空目錄內容
示例代碼
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.StandardCharsets;
?
public class FileUtilsExample {public static void main(String[] args) throws IOException {// 1. 讀取文件為字符串String content = FileUtils.readFileToString(new File("test.txt"), StandardCharsets.UTF_8);System.out.println(content);
?// 2. 寫入字符串到文件FileUtils.writeStringToFile(new File("output.txt"), "Hello Commons IO", StandardCharsets.UTF_8);
?// 3. 復制文件FileUtils.copyFile(new File("source.txt"), new File("dest.txt"));
?// 4. 復制目錄FileUtils.copyDirectory(new File("srcDir"), new File("destDir"));
?// 5. 刪除目錄FileUtils.deleteDirectory(new File("oldDir"));
?// 6. 清空目錄FileUtils.cleanDirectory(new File("tempDir"));}
}

3. FilenameUtils

文件路徑處理工具類。

方法列表與作用
方法作用
getExtension(String)獲取文件擴展名
removeExtension(String)移除文件擴展名
concat(String, String)安全拼接路徑
示例代碼
import org.apache.commons.io.FilenameUtils;
?
public class FilenameUtilsExample {public static void main(String[] args) {// 1. 獲取擴展名String ext = FilenameUtils.getExtension("data.json"); // 返回 "json"
?// 2. 移除擴展名String name = FilenameUtils.removeExtension("image.jpg"); // 返回 "image"
?// 3. 路徑拼接String fullPath = FilenameUtils.concat("/home/user", "docs/file.txt"); // 返回 "/home/user/docs/file.txt"
?System.out.println(ext + ", " + name + ", " + fullPath);}
}

4. FileAlterationObserver

監控文件/目錄變化的工具。

方法作用
  • 監聽文件創建、修改、刪除事件。

示例代碼
import org.apache.commons.io.monitor.*;
import java.io.File;
?
public class FileMonitorExample {public static void main(String[] args) throws Exception {File dir = new File("monitored_dir");FileAlterationObserver observer = new FileAlterationObserver(dir);observer.addListener(new FileAlterationListenerAdaptor() {@Overridepublic void onFileCreate(File file) {System.out.println("文件創建: " + file.getName());}@Overridepublic void onFileDelete(File file) {System.out.println("文件刪除: " + file.getName());}});
?FileAlterationMonitor monitor = new FileAlterationMonitor(1000); // 輪詢間隔1秒monitor.addObserver(observer);monitor.start();
?// 保持程序運行(實際應用可能需要線程管理)Thread.sleep(60_000);monitor.stop();}
}

關鍵說明

//這里涉及到Maven工程管理,意思就是在idea里面下載這個jar包,方便自己使用,可以在我的博客里面找有關于Maven工程的介紹

  1. 依賴引入:需在項目中添加 Commons IO 依賴(如 Maven):

    <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.13.0</version>
    </dependency>
  2. 異常處理:所有示例需處理 IOException(此處簡化為 throws)。

  3. 資源釋放:使用 try-with-resources 確保流自動關閉。

通過這些示例,可以快速實現文件操作、流處理及目錄監控功能。

七、總結

Java的IO流非常強大且靈活,掌握了它,你就能輕松地處理文件、網絡等數據輸入輸出操作。雖然剛開始可能有些晦澀,但通過不斷的實踐和理解,你會逐步熟悉并掌握這些技術。

如果你有其他問題或需要更詳細的案例,隨時留言!希望這篇博客能幫助你順利入門Java IO流。


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

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

相關文章

【后端高階面經:微服務篇】1、微服務架構核心:服務注冊與發現之AP vs CP選型全攻略

一、CAP理論在服務注冊與發現中的落地實踐 1.1 CAP三要素的技術權衡 要素AP模型實現CP模型實現一致性最終一致性&#xff08;Eureka通過異步復制實現&#xff09;強一致性&#xff08;ZooKeeper通過ZAB協議保證&#xff09;可用性服務節點可獨立響應&#xff08;支持分區存活…

QNAP NEXTCLOUD 域名訪問

我是用docker compose方式安裝的&#xff0c;雖然不知道是不是這么個叫法&#xff0c;廢話不多說。 背景&#xff1a;威聯通container station安裝了nextcloud和lucky&#xff0c;lucky進行的域名解析和反代 先在想安裝的路徑、數據存儲路徑、數據庫路徑等新建文件夾。再新建…

高級SQL技巧:窗口函數與復雜查詢優化實戰

高級SQL技巧&#xff1a;窗口函數與復雜查詢優化實戰 開篇&#xff1a;數據庫開發中的挑戰 在現代企業級應用中&#xff0c;數據庫不僅是存儲數據的核心組件&#xff0c;更是處理復雜業務邏輯的重要工具。然而&#xff0c;隨著數據量和并發請求的不斷增長&#xff0c;傳統的S…

《STL--list的使用及其底層實現》

引言&#xff1a; 上次我們學習了容器vector的使用及其底層實現&#xff0c;今天我們再來學習一個容器list&#xff0c; 這里的list可以參考我們之前實現的單鏈表&#xff0c;但是這里的list是雙向循環帶頭鏈表&#xff0c;下面我們就開始list的學習了。 一&#xff1a;list的…

docker中使用openresty

1.為什么要使用openresty 我這邊是因為要使用1Panel&#xff0c;第一個最大的原因&#xff0c;就是圖方便&#xff0c;比較可以一鍵安裝。但以前一直都是直接安裝nginx。所以需要一個過度。 2.如何查看openResty使用了nginx哪個版本 /usr/local/openresty/nginx/sbin/nginx …

vscode包含工程文件路徑

在 VSCode 中配置 includePath 以自動識別并包含上層目錄及其所有子文件夾&#xff0c;需結合通配符和相對/絕對路徑實現。以下是具體操作步驟及原理說明&#xff1a; 1. 使用通配符 ** 遞歸包含所有子目錄 在 c_cpp_properties.json 的 includePath 中&#xff0c;${workspac…

【排序算法】典型排序算法 Java實現

以下是典型的排序算法分類及對應的 Java 實現&#xff0c;包含時間復雜度、穩定性說明和核心代碼示例&#xff1a; 一、比較類排序&#xff08;通過元素比較&#xff09; 1. 交換排序 ① 冒泡排序 時間復雜度&#xff1a;O(n)&#xff08;優化后最優O(n)&#xff09; 穩定性&…

多模態大語言模型arxiv論文略讀(八十七)

MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文標題&#xff1a;MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文作者&#xff1a;Xiangyu Zhao, Xiangtai Li, Haodong Duan, Haian Huang, Yining Li, Kai Chen, Hua Ya…

塔能節能平板燈:點亮蘇州某零售工廠節能之路

在蘇州某零售工廠的運營成本中&#xff0c;照明能耗占據著一定比例。為降低成本、提升能源利用效率&#xff0c;該工廠與塔能科技攜手&#xff0c;引入塔能節能平板燈&#xff0c;開啟了精準節能之旅&#xff0c;并取得了令人矚目的成效。 一、工廠照明能耗困境 蘇州該零售工廠…

數據庫事務的四大特性(ACID)

一、前言 在現代數據庫系統中&#xff0c;事務&#xff08;Transaction&#xff09;是確保數據一致性和完整性的重要機制。事務的四大特性——原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔離性&#xff08;Isolation&#xff09;…

8 種快速易用的Python Matplotlib數據可視化方法

你是否曾經面對一堆復雜的數據&#xff0c;卻不知道如何讓它們變得直觀易懂&#xff1f;別慌&#xff0c;Python 的 Matplotlib 庫是你數據可視化的最佳伙伴&#xff01;它簡單易用、功能強大&#xff0c;能將枯燥的數字變成引人入勝的圖表。無論是學生、數據分析師還是程序員&…

springboot 控制層調用業務邏輯層,注入報錯,無法自動裝配 解決辦法

報錯&#xff1a; 解決&#xff1a;愿意是業務邏輯層&#xff0c;即service層的具體實現類沒有加注解Service導致的&#xff0c;加上解決了&#xff01;&#xff01;

如何提高獨立服務器的安全性?

獨立服務器相對于其它服務器來說&#xff0c;整體的硬件設備都是獨立的同時還有著強大的服務器性能&#xff0c;其中CPU設備能夠決定著服務器的運算能力&#xff0c;所以獨立服務器的安全性受到企業格外的重視&#xff0c;嚴重的話會給企業造成巨大的資金損失。 那么&#xff0…

關于 Web 風險點原理與利用:6. 邏輯風險點

一、分類&#xff1a; 1.1 越權訪問 **越權訪問&#xff08;Authorization Bypass&#xff09;**是指&#xff1a;攻擊者繞過了權限控制機制&#xff0c;訪問或操作了非其權限范圍內的資源或功能。 換句話說&#xff0c;系統該攔你沒攔&#xff0c;你就越權成功了。 1.1.1 …

分布式緩存:ZSET → MGET 跨槽(cross‐slot)/ 并發 GET解決思路

文章目錄 緩存全景圖Pre問題描述解決思路一、管道&#xff08;Pipelining&#xff09;替代多線程二、使用 Hash Tag 保證數據同槽三、用 Hash 結構一次性批量取值四、把數據直接存進 ZSET&#xff08;或用 RedisJSON&#xff09; 小結 緩存全景圖 Pre 分布式緩存&#xff1a;緩…

開發AR導航助手:ARKit+Unity+Mapbox全流程實戰教程

引言 在增強現實技術飛速發展的今天&#xff0c;AR導航應用正逐步改變人們的出行方式。本文將手把手教你使用UnityARKitMapbox開發跨平臺AR導航助手&#xff0c;實現從虛擬路徑疊加到空間感知的完整技術閉環。通過本教程&#xff0c;你將掌握&#xff1a; AR空間映射與場景理…

助力 FPGA 國產化,ALINX 攜多款方案亮相深圳、廣州“紫光同創 FPGA 技術研討會”

5 月中旬&#xff0c;一年一度的紫光同創技術研討會系列活動正式拉開帷幕&#xff0c;相繼在深圳、廣州帶來 FPGA 技術交流盛宴。 ALINX 作為紫光同創官方合作伙伴&#xff0c;長期助力推動 FPGA 國產化應用發展&#xff0c;此次攜多款基于 Kosmo-2 系列產品開發的方案 demo 亮…

LeetCode 1040.移動石子直到連續II

在 X 軸上有一些不同位置的石子。給定一個整數數組 stones 表示石子的位置。 如果一個石子在最小或最大的位置&#xff0c;稱其為 端點石子。每個回合&#xff0c;你可以將一顆 端點石子 拿起并移動到一個未占用的位置&#xff0c;使得該石子不再是一顆 端點石子。 值得注意的…

梯度優化提示詞:精準引導AI分類

基于梯度優化的提示詞工程方法,通過迭代調整提示詞的嵌入向量,使其能夠更有效地引導模型做出正確分類。 數據形式 訓練數據 train_data 是一個列表,每個元素是一個字典,包含兩個鍵: text: 需要分類的文本描述label: 對應的標簽(“沖動"或"理性”)示例數據: …

JavaWeb:SpringBoot配置優先級詳解

3種配置 打包插件 命令行 優先級 SpringBoot的配置優先級決定了不同配置源之間的覆蓋關系&#xff0c;遵循高優先級配置覆蓋低優先級的原則。以下是詳細的優先級排序及配置方法說明&#xff1a; 一、配置優先級從高到低排序 1.命令行參數 優先級最高&#xff0c;通過keyvalu…