java各種流的常見使用方法及示例
流在 Java I/O 操作中扮演著核心角色,主要用于處理數(shù)據(jù)序列(如文件、網(wǎng)絡(luò)連接、內(nèi)存緩沖區(qū)等)。它們主要分為兩大類:字節(jié)流和字符流。
核心概念
- 字節(jié)流: 以字節(jié)為單位進(jìn)行讀寫操作 (
8-bit),適用于所有類型的數(shù)據(jù)(圖片、音頻、視頻、文本等)。基類是InputStream和OutputStream。 - 字符流: 以字符為單位進(jìn)行讀寫操作 (
16-bit),專為處理文本數(shù)據(jù)設(shè)計(jì),能正確處理字符編碼(如UTF-8,GBK)。基類是Reader和Writer。
常用流類及示例
1. 文件字節(jié)流 (FileInputStream / FileOutputStream)
- 用途: 讀寫文件中的原始字節(jié)數(shù)據(jù)。
- 示例: 復(fù)制文件
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
try (InputStream in = new FileInputStream("source.jpg");
OutputStream out = new FileOutputStream("copy.jpg")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
System.out.println("文件復(fù)制完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 緩沖字節(jié)流 (BufferedInputStream / BufferedOutputStream)
- 用途: 包裝其他字節(jié)流,提供緩沖區(qū),減少物理 I/O 次數(shù),顯著提升性能。強(qiáng)烈推薦使用!
- 示例: 高效讀取文件
import java.io.*;
public class BufferedRead {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("data.bin");
BufferedInputStream in = new BufferedInputStream(fis)) {
int data;
while ((data = in.read()) != -1) {
// 處理每個(gè)字節(jié) data
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 數(shù)據(jù)流 (DataInputStream / DataOutputStream)
- 用途: 讀寫 Java 基本數(shù)據(jù)類型 (
int,double,boolean,String等) 的二進(jìn)制表示。 - 示例: 寫入并讀取基本數(shù)據(jù)類型
import java.io.*;
public class DataStreamDemo {
public static void main(String[] args) {
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.dat"))) {
dos.writeInt(100);
dos.writeDouble(3.14);
dos.writeBoolean(true);
dos.writeUTF("你好");
} catch (IOException e) {
e.printStackTrace();
}
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.dat"))) {
int i = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
String s = dis.readUTF();
System.out.println(i + ", " + d + ", " + b + ", " + s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 對(duì)象流 (ObjectInputStream / ObjectOutputStream)
- 用途: 讀寫實(shí)現(xiàn)了 Serializable 接口的 Java 對(duì)象的序列化/反序列化。
- 示例: 序列化對(duì)象到文件
import java.io.*;
class Person implements Serializable {
private String name;
private transient int age; // transient 修飾的字段不會(huì)被序列化
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// ... Getters, Setters, toString ...
}
public class ObjectStreamDemo {
public static void main(String[] args) {
Person person = new Person("張三", 30);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
Person readPerson = (Person) ois.readObject();
System.out.println(readPerson); // 注意 age 字段為默認(rèn)值 0 (未序列化)
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
5. 文件字符流 (FileReader / FileWriter)
- 用途: 讀寫文本文件內(nèi)容,按字符處理。注意編碼問題! 默認(rèn)使用平臺(tái)默認(rèn)編碼。
- 示例: 讀取文本文件
import java.io.*;
public class FileReadWrite {
public static void main(String[] args) {
try (Reader reader = new FileReader("input.txt");
Writer writer = new FileWriter("output.txt")) {
char[] buffer = new char[1024];
int charsRead;
while ((charsRead = reader.read(buffer)) != -1) {
writer.write(buffer, 0, charsRead);
}
System.out.println("文本文件復(fù)制完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
6. 緩沖字符流 (BufferedReader / BufferedWriter)
- 用途: 包裝其他字符流,提供緩沖區(qū)和便捷方法(如
readLine()讀取整行文本)。提升文本處理效率。 - 示例: 逐行讀取文本文件
import java.io.*;
public class BufferedReaderDemo {
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();
}
}
}
7. 轉(zhuǎn)換流 (InputStreamReader / OutputStreamWriter)
- 用途: 橋梁作用! 將字節(jié)流轉(zhuǎn)換為字符流,并可顯式指定字符編碼。解決亂碼問題的關(guān)鍵。
- 示例: 按指定編碼讀取文件
import java.io.*;
public class EncodingDemo {
public static void main(String[] args) {
try (InputStream fis = new FileInputStream("input_gbk.txt");
// 將字節(jié)流 fis 轉(zhuǎn)換為字符流,并指定編碼為 GBK
Reader isr = new InputStreamReader(fis, "GBK");
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line); // 正確顯示 GBK 編碼的中文
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
8. 打印流 (PrintStream / PrintWriter)
- 用途: 提供方便的打印方法 (
print,println,printf),自動(dòng)將各種類型的數(shù)據(jù)轉(zhuǎn)換為文本輸出。System.out就是一個(gè)PrintStream。 - 示例: 格式化輸出到文件
import java.io.*;
public class PrintWriterDemo {
public static void main(String[] args) {
try (PrintWriter pw = new PrintWriter(new FileWriter("log.txt"))) {
pw.println("日志開始:");
pw.printf("時(shí)間: %tT%n", System.currentTimeMillis());
pw.println("操作: 用戶登錄");
pw.println("日志結(jié)束.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
9. 管道流 (PipedInputStream / PipedOutputStream / PipedReader / PipedWriter)
- 用途: 實(shí)現(xiàn)線程間的通信。一個(gè)線程通過
PipedOutputStream/PipedWriter寫入數(shù)據(jù),另一個(gè)線程通過對(duì)應(yīng)的PipedInputStream/PipedReader讀取數(shù)據(jù)。必須連接使用! - 示例: 線程間通信
import java.io.*;
public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos); // 連接管道
Thread writerThread = new Thread(() -> {
try (DataOutputStream dos = new DataOutputStream(pos)) {
dos.writeUTF("Hello from writer thread!");
} catch (IOException e) {
e.printStackTrace();
}
});
Thread readerThread = new Thread(() -> {
try (DataInputStream dis = new DataInputStream(pis)) {
String message = dis.readUTF();
System.out.println("Reader thread received: " + message);
} catch (IOException e) {
e.printStackTrace();
}
});
writerThread.start();
readerThread.start();
}
}
總結(jié)與選擇建議
| 流類型 | 典型類 | 主要用途 | 特點(diǎn)/注意點(diǎn) |
|---|---|---|---|
| 字節(jié)流 | FileInputStream, FileOutputStream | 原始字節(jié)數(shù)據(jù)讀寫 | 基礎(chǔ)文件操作 |
BufferedInputStream, BufferedOutputStream | 提高字節(jié)流效率 | 強(qiáng)烈推薦包裝使用 | |
DataInputStream, DataOutputStream | 讀寫基本數(shù)據(jù)類型 | 二進(jìn)制格式 | |
ObjectInputStream, ObjectOutputStream | 對(duì)象序列化/反序列化 | 對(duì)象需實(shí)現(xiàn) Serializable | |
PipedInputStream, PipedOutputStream | 線程間字節(jié)通信 | 必須成對(duì)連接 | |
| 字符流 | FileReader, FileWriter | 文本文件讀寫 | 注意編碼(默認(rèn)平臺(tái)編碼) |
BufferedReader, BufferedWriter | 提高字符流效率,支持readLine() | 推薦用于文本處理 | |
InputStreamReader, OutputStreamWriter | 字節(jié)流->字符流轉(zhuǎn)換,指定編碼 | 解決亂碼的關(guān)鍵 | |
PrintStream, PrintWriter | 格式化打印輸出 | System.out 是 PrintStream | |
PipedReader, PipedWriter | 線程間字符通信 | 必須成對(duì)連接 |
選擇原則:
- 數(shù)據(jù)類型: 處理二進(jìn)制數(shù)據(jù)(圖片、音頻等)用字節(jié)流;處理文本數(shù)據(jù)優(yōu)先考慮字符流。
- 性能: 使用
BufferedXxx包裝流提高效率。 - 功能: 根據(jù)需求選擇特定功能的流(如讀寫基本類型用
DataXxx,序列化用ObjectXxx)。 - 編碼: 處理文本時(shí),務(wù)必關(guān)注編碼。使用
InputStreamReader/OutputStreamWriter明確指定編碼。 - 資源管理: 使用
try-with-resources語句確保流正確關(guān)閉,避免資源泄漏。
總結(jié)
到此這篇關(guān)于java各種流的常見使用方法及示例的文章就介紹到這了,更多相關(guān)java常用流類示例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過java備份恢復(fù)mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了如何通過java備份恢復(fù)mysql數(shù)據(jù)庫(kù),其實(shí)一般情況下通過bat或sh就可以,這里主要是介紹了java的實(shí)現(xiàn)思路,喜歡的朋友可以參考下2013-09-09
Java redis存Map對(duì)象類型數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了Java redis存Map<String,RedisCustom>對(duì)象類型數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
解決springboot的aop切面不起作用問題(失效的排查)
這篇文章主要介紹了解決springboot的aop切面不起作用問題(失效的排查),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。 一起跟隨小編過來看看吧2020-04-04
springBoot項(xiàng)目配置文件加載優(yōu)先級(jí)及同配置覆蓋問題詳解
SpringBoot配置?件可以放置在多種路徑下,不同路徑下的配置優(yōu)先級(jí)有所不同,下面這篇文章主要給大家介紹了關(guān)于springBoot項(xiàng)目配置文件加載優(yōu)先級(jí)及同配置覆蓋問題的相關(guān)資料,需要的朋友可以參考下2023-05-05
Java處理Word文檔里的Excel表格數(shù)據(jù)(附源碼)
這篇文章主要為大家詳細(xì)介紹了如何使用Java處理Word文檔里的Excel表格數(shù)據(jù)并附上了源碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2025-07-07
Java中Socket實(shí)現(xiàn)數(shù)據(jù)通信的示例代碼
本文主要介紹了Java中Socket實(shí)現(xiàn)數(shù)據(jù)通信的示例代碼,Socket可以建立起客戶端和服務(wù)器之間的連接,實(shí)現(xiàn)數(shù)據(jù)的傳輸和交互,感興趣的可以了解一下2023-09-09
SpringBoot上傳文件并配置本地資源映射來訪問文件的實(shí)例代碼
這篇文章主要介紹了SpringBoot上傳文件并配置本地資源映射來訪問文件的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Java 中導(dǎo)出 Excel 文件的常見實(shí)現(xiàn)方法
這篇文章給大家介紹Java 中導(dǎo)出 Excel 文件的常見實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-09-09

