最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java字節(jié)流FileInputStream和FileOutputStream從入門到實踐

 更新時間:2026年06月06日 09:59:10   作者:一團(tuán)柳絮  
FileOutputStream 是與 FileInputStream 相對應(yīng)的文件輸出流類,用來實現(xiàn)向文件中寫入數(shù)據(jù),寫入數(shù)據(jù)的基本單位是字節(jié),這篇文章主要介紹了Java字節(jié)流FileInputStream和FileOutputStream從入門到實踐的相關(guān)資料,需要的朋友可以參考下

一、前言

在 Java 中,文件的讀寫操作是最基礎(chǔ)也是最高頻的 I/O 場景之一。字節(jié)流(Byte Stream)作為 Java I/O 體系的兩大分支之一,負(fù)責(zé)處理所有二進(jìn)制數(shù)據(jù)的傳輸,圖片、音頻、視頻以及任何非文本文件都離不開它。FileInputStreamFileOutputStream 是字節(jié)流中最核心的兩個實現(xiàn)類,掌握它們就掌握了 Java 文件 I/O 的基石。

本文將圍繞這兩個類的構(gòu)造、核心方法、使用方式、底層原理以及常見坑點展開,確保看完后能寫出健壯的文件讀寫代碼。

二、字節(jié)流簡介

Java 的 I/O 流分為兩大類:

  • 字節(jié)流(Byte Stream):以 InputStream / OutputStream 為抽象父類,按字節(jié)(8 bit)讀寫,適合所有類型的文件。
  • 字符流(Character Stream):以 Reader / Writer 為抽象父類,按字符(16 bit)讀寫,適合純文本文件。

FileInputStreamFileOutputStream 分別繼承自 InputStreamOutputStream,是操作文件的直接入口。

 InputStream (抽象)
    └── FileInputStream    ← 從文件讀取字節(jié)
 OutputStream (抽象)
    └── FileOutputStream   ← 向文件寫入字節(jié)

三、核心 API 速覽

3.1 FileInputStream

方法簽名說明
FileInputStream(String name)根據(jù)文件路徑創(chuàng)建輸入流
FileInputStream(File file)根據(jù) File 對象創(chuàng)建輸入流
int read()讀取一個字節(jié),返回 0~255 的 int,讀到末尾返回 -1
int read(byte[] b)讀取最多 b.length 個字節(jié)到數(shù)組,返回實際讀取的字節(jié)數(shù)
int read(byte[] b, int off, int len)讀取最多 len 個字節(jié)到數(shù)組的指定偏移位置
long skip(long n)跳過并丟棄 n 個字節(jié)
int available()返回可讀的字節(jié)數(shù)估計值
void close()關(guān)閉流,釋放系統(tǒng)資源

3.2 FileOutputStream

方法簽名說明
FileOutputStream(String name)根據(jù)路徑創(chuàng)建輸出流(覆蓋模式)
FileOutputStream(String name, boolean append)指定是否追加模式
FileOutputStream(File file)根據(jù) File 對象創(chuàng)建輸出流
void write(int b)寫入一個字節(jié)(只取 int 的低 8 位)
void write(byte[] b)寫入整個字節(jié)數(shù)組
void write(byte[] b, int off, int len)寫入數(shù)組的一部分
void flush()刷新緩沖區(qū)(字節(jié)流 flush 是空實現(xiàn),但遵循約定)
void close()關(guān)閉流,釋放系統(tǒng)資源

四、代碼實現(xiàn)

4.1 基礎(chǔ)用法:單個字節(jié)讀寫(不推薦用于大文件)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileInputStreamDemo {

    public static void main(String[] args) throws IOException {
        // 用 try-with-resources 自動關(guān)閉流(JDK 7+)
        try (FileInputStream fis = new FileInputStream("source.txt");
             FileOutputStream fos = new FileOutputStream("dest.txt")) {

            int data;
            while ((data = fis.read()) != -1) {
                fos.write(data);
            }
        }
        System.out.println("文件復(fù)制完成");
    }
}

缺點:每次只讀寫一個字節(jié),每次 read()/write() 都涉及一次 native 調(diào)用,大文件下性能極差。

4.2 推薦用法:字節(jié)數(shù)組批量讀寫

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopyWithBuffer {

    public static void main(String[] args) {
        String source = "photo.jpg";
        String dest = "photo_copy.jpg";

        try (FileInputStream fis = new FileInputStream(source);
             FileOutputStream fos = new FileOutputStream(dest)) {

            byte[] buffer = new byte[8192]; // 8KB 緩沖區(qū)
            int len;

            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                // 注意:必須使用 write(buffer, 0, len) 而不是 write(buffer)
                // 因為最后一次讀取可能不足 8192 字節(jié)
            }

            System.out.println("復(fù)制完成");

        } catch (IOException e) {
            System.err.println("文件操作失敗: " + e.getMessage());
        }
    }
}

4.3 追加模式寫入

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileAppendDemo {

    public static void main(String[] args) {
        try (FileOutputStream fos = new FileOutputStream("log.txt", true)) {
            String line = "[" + System.currentTimeMillis() + "] 用戶登錄成功\n";
            fos.write(line.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FileOutputStream 的第二個參數(shù) appendtrue 時,寫入內(nèi)容追加到文件末尾而非覆蓋。

五、執(zhí)行流程與底層原理

read(byte[]) 為例,一次讀取的完整鏈路如下:

  1. Java 應(yīng)用層 調(diào)用 FileInputStream.read(byte[])
  2. JDK 內(nèi)部 調(diào)用 native readBytes 方法
  3. JNI 進(jìn)入 C 層,調(diào)用操作系統(tǒng)的 ReadFile(Windows)或 read()(Linux/POSIX)
  4. 內(nèi)核 從磁盤讀取數(shù)據(jù)到內(nèi)核空間緩沖區(qū)
  5. 內(nèi)核 → 用戶空間 數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到 Java 傳入的 byte 數(shù)組
  6. 返回實際讀取的字節(jié)數(shù)(-1 表示 EOF)

這個過程中涉及一次用戶態(tài) ↔ 內(nèi)核態(tài)切換和一次數(shù)據(jù)拷貝。這也是為什么批量讀(減少 native 調(diào)用次數(shù))比逐字節(jié)讀快幾個數(shù)量級的原因。

六、常見問題與注意事項

6.1 流必須關(guān)閉

未關(guān)閉流會導(dǎo)致文件句柄泄漏,最終可能觸發(fā) Too many open files 異常。

? 正確做法:優(yōu)先使用 try-with-resources(JDK 7+),它會自動調(diào)用 close(),即使在異常發(fā)生時也能正確關(guān)閉。

6.2write(byte[])和write(byte[], 0, len)的區(qū)別

fos.write(buffer) 會把整個 buffer 寫入文件。如果最后一次讀取不足 buffer 長度,會寫入上一次殘留的臟數(shù)據(jù)。永遠(yuǎn)使用 write(buffer, 0, len)。

6.4 字符編碼問題

字節(jié)流不涉及編碼轉(zhuǎn)換,寫入什么字節(jié)就讀出什么字節(jié)。如果要在字節(jié)流上處理文本,必須外部指定字符集

// 寫入時指定編碼
fos.write("中文".getBytes(StandardCharsets.UTF_8));

// 讀取時指定編碼
String text = new String(bytes, StandardCharsets.UTF_8);

6.5 FileNotFoundException 不等于文件不存在

FileInputStream 構(gòu)造時如果文件不存在會拋 FileNotFoundException。但如果文件是個目錄,或者路徑包含不可讀的目錄,同一異常也會拋出。不要只把它當(dāng)成"文件不存在"來處理。

七、最佳實踐

  1. 能用字符流的場景(純文本)用字符流,否則用字節(jié)流。FileReader / FileWriter 內(nèi)部封裝了字節(jié)轉(zhuǎn)換,更省心。
  2. 大文件優(yōu)先用 BufferedInputStream / BufferedOutputStream 包裝,它們在內(nèi)部自動維護(hù)更大的緩沖區(qū),減少 native 調(diào)用。
  3. 版本兼容檢查 — FileInputStream 和 FileOutputStream 從 JDK 1.0 就有,不存在兼容性問題。
  4. Files.copy() 可以替代 — 對于單純復(fù)制文件,java.nio.file.Files.copy() 一行代碼搞定,底層使用更高效的 FileChannel。
// NIO 一行復(fù)制
Files.copy(Path.of("source.txt"), Path.of("dest.txt"), StandardCopyOption.REPLACE_EXISTING);

八、總結(jié)

  • FileInputStreamFileOutputStream 是 Java 字節(jié)流體系中最基礎(chǔ)的文件讀寫類,支持所有文件類型。
  • 批量讀寫(字節(jié)數(shù)組)比逐字節(jié)讀寫性能高出幾個數(shù)量級。
  • 始終使用 try-with-resources 確保流被正確關(guān)閉。
  • 寫入時注意 write(buffer, 0, len) 而非 write(buffer),避免臟數(shù)據(jù)。
  • 純文本場景優(yōu)先考慮 FileReader / FileWriter 或 NIO 的 Files 工具類。

掌握字節(jié)流是理解 Java I/O 體系的第一步,也是編寫高可靠文件操作代碼的必備基礎(chǔ)。

推薦標(biāo)簽:

  • Java IO
  • FileInputStream
  • FileOutputStream
  • 字節(jié)流
  • Java 文件操作

到此這篇關(guān)于Java字節(jié)流FileInputStream和FileOutputStream從入門到實踐的文章就介紹到這了,更多相關(guān)Java字節(jié)流FileInputStream和FileOutputStream內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JVM之參數(shù)分配(全面講解)

    JVM之參數(shù)分配(全面講解)

    下面小編就為大家?guī)硪黄狫VM之參數(shù)分配(全面講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Spring Boot 整合 Minio 實現(xiàn)高效文件存儲解決方案(本地和線上)

    Spring Boot 整合 Minio 實現(xiàn)高效文件存儲解決方案(本地和線上)

    Minio 是一個高性能的分布式對象存儲系統(tǒng),專為云原生應(yīng)用而設(shè)計,本文將詳細(xì)介紹如何在Spring Boot項目中集成Minio實現(xiàn)高效文件存儲,實現(xiàn)文件的上傳、下載、刪除等核心功能,感興趣的朋友一起看看吧
    2025-08-08
  • springboot如何配置ssl支持https

    springboot如何配置ssl支持https

    在SpringBoot應(yīng)用中配置SSL支持HTTPS需要創(chuàng)建KeyStore并在application.yml中進(jìn)行相應(yīng)配置,首先,使用java的keytool工具創(chuàng)建KeyStore,這涉及到設(shè)置密鑰對、指定密鑰算法(RSA)、密鑰大小(2048位)、密鑰庫名稱、證書有效期等,創(chuàng)建KeyStore后
    2024-10-10
  • spring boot整合CAS Client實現(xiàn)單點登陸驗證的示例

    spring boot整合CAS Client實現(xiàn)單點登陸驗證的示例

    本篇文章主要介紹了spring boot整合CAS Client實現(xiàn)單點登陸驗證的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • SpringBean依賴和三級緩存的案例講解

    SpringBean依賴和三級緩存的案例講解

    這篇文章主要介紹了SpringBean依賴和三級緩存的案例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 一文帶你掌握J(rèn)ava8強(qiáng)大的StreamAPI

    一文帶你掌握J(rèn)ava8強(qiáng)大的StreamAPI

    Java8API添加了一個新的抽象稱為流Stream,可以讓你以一種聲明的方式處理數(shù)據(jù)。Stream 使用一種類似用SQL 語句從數(shù)據(jù)庫查詢數(shù)據(jù)的直觀方式來提供一種對 Java 集合運算和表達(dá)的高階抽象。Stream API可以極大提高Java程序員的生產(chǎn)力,讓程序員寫出高效率、干凈、簡潔的代碼
    2021-10-10
  • SpringBoot集成Redis使用Lettuce詳解

    SpringBoot集成Redis使用Lettuce詳解

    文章首先介紹了Redis的基礎(chǔ)數(shù)據(jù)類型,包括String、List、Set、Zset和Hash,然后介紹了Redis常用連接池,包括Jedis、Redisson和Lettuce,最后,通過一個SpringBoot集成Redis的案例,詳細(xì)說明了yml配置、引入依賴、配置類和工具類的編寫
    2026-05-05
  • javascript fetch 用法講解

    javascript fetch 用法講解

    fetch 是一個現(xiàn)代化的 JavaScript API,用于發(fā)送網(wǎng)絡(luò)請求并獲取資源,它是瀏覽器提供的全局方法,可以替代傳統(tǒng)的 XMLHttpRequest,這篇文章主要介紹了javascript fetch 用法講解,需要的朋友可以參考下
    2025-05-05
  • java.lang.annotation包詳細(xì)介紹

    java.lang.annotation包詳細(xì)介紹

    java.lang.annotation?包是 Java 標(biāo)準(zhǔn)庫中的一個核心包,專門用于定義和支持 Java 注解(Annotation),這篇文章主要介紹了java.lang.annotation包介紹,需要的朋友可以參考下
    2024-07-07
  • Maven?Settings.xml的基本語法詳解

    Maven?Settings.xml的基本語法詳解

    這篇文章主要為大家介紹了Maven?Settings.xml的基本語法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11

最新評論

湘乡市| 英德市| 明水县| 淮北市| 旬邑县| 垫江县| 韩城市| 高陵县| 佛学| 思茅市| 镇坪县| 舒兰市| 鸡泽县| 斗六市| 苗栗市| 改则县| 涟源市| 东城区| 抚州市| 德昌县| 田林县| 建宁县| 新丰县| 项城市| 达拉特旗| 水城县| 澜沧| 犍为县| 揭阳市| 金阳县| 建德市| 垦利县| 图木舒克市| 西乡县| 凤凰县| 庆阳市| 松溪县| 石屏县| 隆化县| 遂平县| 明光市|