day36-IO流03

来源:https://www.cnblogs.com/liyuelian/archive/2022/09/11/16684898.html
-Advertisement-
Play Games

JavaIO流03 4.常用的類02 4.4節點流和處理流 4.4.1基本介紹 節點流可以從一個特定的數據源讀寫數據,如FileReader、FileWriter 數據源就是存放數據的地方,比如文件、數組、字元串、管道等 處理流(也叫包裝流)是“連接”在已經存在的流(節點流或者處理流)之上,為程式提 ...


JavaIO流03

4.常用的類02

4.4節點流和處理流

202209111555

4.4.1基本介紹

  1. 節點流可以從一個特定的數據源讀寫數據,如FileReader、FileWriter

    數據源就是存放數據的地方,比如文件、數組、字元串、管道等

  1. 處理流(也叫包裝流)是“連接”在已經存在的流(節點流或者處理流)之上,為程式提供更為強大的讀寫功能,也更加靈活,如BufferedReader、BufferedWriter

  • 節點流和處理流的區別和聯繫:
  1. 節點流是底層流(低級流),直接和數據源相連接。
  2. 處理流(包裝流)對節點流進行了包裝,既可以消除不同節點流的實現差異,也可以提供更方便的方法來完成輸入輸出。
  3. 處理流對節點流進行了包裝,使用了修飾器的設計模式,不會直接與數據源相連接。

image-20220911162032590

  • 處理流特點:

    1.性能的提高:主要以增加緩衝的方式來提高輸入輸出的效率。

    2.操作的便捷:處理流提供了一系列便捷的方法來一次輸入輸出大批量的數據,使用更加靈活方便。

4.4.2模擬包裝流-修飾器模式

Reader_:

package li.io;

/**
 * 模擬包裝流的修飾器模式
 */
public abstract class Reader_ {//抽象類
    public void readFile() {}
    public void readString() {}
}

FileReader_:

package li.io;

public class FileReader_ extends Reader_ {//模擬節點流

    public void readFile() {
        System.out.println("對文件進行讀取...");
    }
}

StringReader_:

package li.io;

public class StringReader_ extends Reader_ {//模擬節點流

    public void readString() {
        System.out.println("讀取字元串...");
    }
}

BufferedReader_:

package li.io;

/**
 * 模擬處理流(包裝流)
 */
public class BufferedReader_ extends Reader_ {
    private Reader_ reader_;//屬性是Reader_類型

    public BufferedReader_(Reader_ reader_) {
        this.reader_ = reader_;
    }

    public void readFile(){//封裝一層
        reader_.readFile();
    }

    //讓方法更加靈活,比如多次讀取文件,或者加緩衝byte[]...
    public void readFile(int num) {
        for (int i = 0; i < num; i++) {
            reader_.readFile();
        }
    }

    //又如擴展readString方法,例如批量處理字元串數據...
    public void readString(int num) {
        for (int i = 0; i < num; i++) {
            reader_.readString();
        }
    }
}

Test_:

package li.io;

public class Test_ {
    public static void main(String[] args) {

        BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
        bufferedReader_.readFile(3);
        bufferedReader_.readFile();

        BufferedReader_ bufferedReader02_ = new BufferedReader_(new StringReader_());
        bufferedReader02_.readString(2);
    }
}
image-20220911170145151

4.4.3字元處理流-BufferedReader&BufferedWriter

  • BufferedReader和BufferedWriter屬於字元流,是按照字元來讀取數據的

  • 在關閉流時,只需要關閉外層流(即包裝流)即可

  1. BufferedReader構造方法:
image-20220911190546610

BufferedReader常用方法:

public int read() throws IOException
//讀取單個字元。
//作為一個整數(其範圍從 0 到 65535 (0x00-0xffff))讀入的字元,如果已到達流末尾,則返回 -1
    
public int read(char[] cbuf) throws IOException
//一次讀取一個位元組數組
//cbuf - 目標緩衝區
//讀取的字元數,如果已到達流的末尾,則返回 -1 
    
public void close() throws IOException
//關閉該流並釋放與之關聯的所有資源。    
    
public String readLine() throws IOException
//讀取一個文本行。通過下列字元之一即可認為某行已終止:換行 (’\n’)、回車 (’\r’) 或回車後直接跟著換行。
//包含該行內容的字元串,不包含任何行終止符,如果已到達流末尾,則返回 nu    
  1. BufferedWriter構造方法:
image-20220911191826697

BufferedWriter常用方法:

void write(char ch);//寫入單個字元。

void write(char []cbuf,int off,int len)//寫入字元數據的某一部分。

void write(String s,int off,int len)//寫入字元串的某一部分。

void newLine()//寫入一個行分隔符。

void flush();//刷新該流中的緩衝。將緩衝數據寫到目的文件中去。

void close();//關閉此流,在關閉前會先刷新

應用案例1:使用BufferedReader讀取文本文件,並顯示在控制台

package li.io.reader_;

import java.io.BufferedReader;
import java.io.FileReader;


//演示BufferedReader的使用
public class BufferedReader_ {
    public static void main(String[] args) throws Exception {
        String filePath = "d:\\note.txt";
        //創建
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));

        //讀取
        String line;
        //readLine():按行讀取文件,當返回null時,表示文件讀取完畢
        while((line = bufferedReader.readLine())!=null){
            System.out.println(line);
        }

        //關閉流:這裡只需要關閉BufferedReader,底層會去自動地關閉節點流
        bufferedReader.close();
    }
}
image-20220911173953400

思考:為什麼只需要關閉外層流?

在代碼bufferedReader.close();處打上斷點,點擊force step into,可以看到下圖所示:

在底層調用的其實是:傳進去的節點流對象的close()方法

這裡的in就是我們傳入的new FileReader(filePath)

image-20220911174246035

應用案例2:使用BufferedWriter將“一隻可愛的小貓咪”寫入到文件中

package li.io.writer_;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

//演示BufferedWriter的使用
public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\ok.txt";

        //創建BufferedWriter對象
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));

        //寫入
        bufferedWriter.write("一隻可愛的小貓咪");
        bufferedWriter.newLine();//插入一個和系統相關的換行
        bufferedWriter.write("兩隻可愛的小貓咪");
        bufferedWriter.newLine();
        bufferedWriter.write("三隻可愛的小貓咪");
        bufferedWriter.newLine();

        //關閉外層流即可,底層自動關閉穿入的內層流
        bufferedWriter.close();
    }
}
image-20220911180355401

案例3:綜合使用 BufferedReader & BufferedWriter 完成文件文本拷貝,註意文件編碼。

package li.io.writer_;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class BufferedCopy_ {
    public static void main(String[] args) throws Exception {
        //註意:BufferedReader 和 BufferedWriter都是字元流操作
        // 不要去操作二進位文件[聲音,視頻,doc,pdf等],可能造成文件損壞

        String srcFilePath = "d:\\note.txt";//源文件
        String destFilePath = "d:\\note2.txt";
        String line = null;

        //創建BufferedReader&BufferedWriter對象
        BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));

        //讀入和寫出
        while ((line = bufferedReader.readLine()) != null) {//每讀取一行內容就寫入
            bufferedWriter.write(line);
            bufferedWriter.newLine();//換行
        }

        System.out.println("拷貝完畢~");

        //關閉兩個外層流
        bufferedReader.close();
        bufferedWriter.close();
    }
}
image-20220911182717923

4.4.4位元組處理流-BufferedInputStream&BufferedOutputStream

  1. BufferedInputStream

    BufferedInputStream是位元組流,在創建BufferedInputStream時會創建一個內部緩衝區數組。

常用方法:

int available()
//用於返回輸入流中可用的未讀位元組數,而不會由於下一次為此InputStream的方法的調用而阻塞。

void close()
//關閉此輸入流並釋放與該流關聯的所有系統資源。

void mark(int readlimit)
//輸入流的當前位置做個標記,readlimit參數是輸入流在標記位置失效前允許讀取的位元組數。

boolean markSupported()
//測試輸入流是否支持mark和reset方法。

int read()
//讀取一個位元組。

int read(byte[] b, int off, int len)
//讀取多個位元組到位元組數組b中,參數off是數組偏移量,參數len是讀取數據的長度。

void reset()
//重置流的當前位置到前面標記的位置。

long skip(long n)
//略過流中的數據。若數據不夠時,跳過僅有的位元組,返回跳過的位元組數。
  1. BufferedOutputStream

    BufferedOutputStream是位元組流,實現緩衝的輸出流,可以將多個位元組寫入底層的輸出流中,而不必對每次位元組寫入調用底層系統

    image-20220911203633605 image-20220911203655940

應用案例:

要求:編程完成圖片/音樂的拷貝(要求使用 BufferedInputStream 和 BufferedOutputStream 流)

package li.io.outputstream_;

import java.io.*;

/**
 * 演示使用 BufferedInputStream 和 BufferedOutputStream
 * 使用它們可以拷貝二進位文件
 * 同時也可以拷貝文本文件
 */

public class BufferedCopy02 {
    public static void main(String[] args) {
        String srcFilePath = "d:\\蘭亭序 - 周傑倫.mp3";
        String destFilePath = "d:\\ltx-zhou.mp3";

        //創建BufferedInputStream 和 BufferedOutputStream對象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
            //迴圈寫入並讀取
            byte[] buf = new byte[1024];
            int readLen = 0;
            //read(byte[]):當返回-1時就表示文件讀取完畢
            while ((readLen = bis.read(buf)) != -1) {
                bos.write(buf, 0, readLen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //關閉外層流
            try {
                if (bos != null) {
                    bos.close();
                }
                if (bis != null) {
                    bis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

image-20220911212413416

註意:位元組流可以操作二進位文件,同時也可以操作文本文件


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 別人寫的 地址鏈接 視頻鏈接: https://www.bilibili.com/video/BV1TK4y1Q78s github鏈接: https://github.com/Lavender-z/demo 如果上不了,就下個dev-sidecar代理 效果 代碼註釋 <!DOCTYPE ht ...
  • Singleton Pattern 單例模式,作為創建型模式的一種,其保證了類的實例對象只有一個,並對外提供此唯一實例的訪問介面 概述 對於單例模式而言,其最核心的目的就是為了保證該類的實例對象是唯一的。為此一方面,需要將該類的構造函數設為private,另一方面,該類需要在內部完成實例的構造並對外 ...
  • 裝飾者模式是一種結構型模型,是動態的給對象增加職責,對於新增功能來說要比通過子類方式更加的靈活。他允許對一個對象進行添加新的功能,但不能改變結構。 ...
  • 一篇文章帶你掌握主流資料庫框架——MyBatis MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。 在之前的文章中我們學習了MYSQL和JDBC,但是這些東西遠遠不足以支持我們書寫JavaWeb相關的內容 在學習MyBatis前,請先學習Java,Mysql,JD ...
  • 緩存穿透是用戶訪問一個不存在的key,導致請求穿透到資料庫。 問題關鍵是程式上要識別出這個key是一個錯誤key,不是由系統生成的key。每次添加或刪除緩存時維護一個key欄位查詢過濾器,例如:布隆過濾器、HashSet。這樣在訪問緩存前,可以對key先進行查詢過濾,判斷key是否存在,再往下執行業 ...
  • 上一篇說到緩存的更新操作是非冪等操作,會出現併發更新的問題。那用緩存刪除操作實現緩存更新行不行,您可能覺得奇怪,刪除了緩存如何更新,假設讀業務先讀取緩存,如果發現沒有就回溯到讀資料庫找數據,然後再更新回緩存。這種方式叫做懶載入,是在查詢到資料庫時,主動更新緩存。就是說刪除同樣能達到更新緩存的目的,為 ...
  • 為什麼緩存與資料庫要結合使用,使用緩存的目的是為了減少用戶請求穿透到服務端和資料庫,儘量將資源放置在離用戶更近的地方,讓用戶能夠更快得到應答。在一些活動大促、秒殺場景中,經常會面臨突然的流量爆發,造成系統的高併發訪問。例如秒殺商品的詳情頁內容提前預熱到緩存中,能緩解資料庫讀取壓力。但在高併發下,緩存 ...
  • 一個菜鳥的設計模式之旅,使用 Golang 實現。本程式實現狀態模式。一個玩家從滿血到死亡的過程有多個狀態,假定健康、輕傷、重傷、死亡狀態,當玩家扣血時判斷切換狀態,更改對象的行為。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...