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

一文徹底弄懂Java中I/O操作

 更新時間:2025年11月27日 09:21:36   作者:IsLand1314~  
Java中的IO流操作是Java編程中非常重要的一部分,用于處理數(shù)據(jù)的輸入和輸出,這篇文章主要介紹了Java中I/O操作的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

1. 引言

??I/O 操作主要是指 使用 Java 程序完成輸入(Input)、輸出(Output) 操作。輸入是指將文件內(nèi)容以數(shù)據(jù)流的形式讀入內(nèi)存,輸出是指通過 Java 程序?qū)?nèi)容中的數(shù)據(jù)寫入文件,輸入輸出操作在實際開發(fā)中比較廣泛。

  1. IO:輸入/輸出(Input/Output)
  2. 流:是一種抽象概念,是對數(shù)據(jù)傳輸?shù)目偡Q.也就是說數(shù)據(jù)在設(shè)備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸
  3. IO流就是用來處理設(shè)備間數(shù)據(jù)傳輸問題的.常見的應(yīng)用: 文件復(fù)制; 文件上傳; 文件下載

IO流的分類:

(1)按照數(shù)據(jù)的流向

  • 輸入流:讀數(shù)據(jù)
  • 輸出流:寫數(shù)據(jù)

(2)按照數(shù)據(jù)類型來分:

  1. 字節(jié)流
    • 字節(jié)輸入流
    • 字節(jié)輸出流
  2. 字符流
    • 字符輸入流
    • 字符輸出流

IO流的使用場景

  1. 如果操作的是純文本文件,優(yōu)先使用字符流
  2. 如果操作的是圖片、視頻、音頻等二進制文件,優(yōu)先使用字節(jié)流
  3. 如果不確定文件類型,優(yōu)先使用字節(jié)流,字節(jié)流是萬能的流

2. File 類

java.io 包中的 File 類 是唯一一個可以代表磁盤文件的對象,它定義了一些用于操作文件的方法。通過調(diào)用 File 類 提供的各種方法,可以創(chuàng)建、刪除或者重命名文件,判斷硬盤上某個文件是否存在,查詢文件最后修改時間,等等。本節(jié)將針對File 類 進行詳細講解。創(chuàng)建File對象

2.1 創(chuàng)建 File 對象

File 類 提供了多個構(gòu)造方法用于創(chuàng)建 File 對象。File 類 的常用構(gòu)造方法如下所示:

方法聲明功能描述
FILE(String pathname)通過指定的 一個字符串類型的文件路徑 創(chuàng)建一個 FILE 對象
FILE(String parent, String child)根據(jù)指定的 一個字符串類型的父路徑和一個字符串類型的子路徑(包括文件名稱)創(chuàng)建一個 FILE 對象
FILE (FILE parent, String child)根據(jù)指定的 一個FILE 類的父路徑和一個字符串類型的子路徑(包括文件名稱)創(chuàng)建一個 FILE 對象

所有的構(gòu)造方法都需要傳入文件路徑,那么我們應(yīng)該如何去用呢?

  • 如果程序只處理一個目錄和文件,并且知道該目錄或文件的路徑,就建議使用 構(gòu)造 1
  • 如果程序處理的是一個公共目錄中的若干子目錄或文件,就建議使用 構(gòu)造 2 和 構(gòu)造 3

案例:

public static void main(String[] args) {
    // 方法一:通過絕對路徑創(chuàng)建
    File f1 = new File("D:\\file\\a.txt");
    // 方法二:通過相對路徑創(chuàng)建
    File f2 = new File("src\\Hello.txt");
}

注:目錄符號(\) 用 \\ 表示,因為 \ 在Java中是特殊字符,具有轉(zhuǎn)義作用,因此用 \\ 表示,此外我們也可以用 / 來作目錄符號。

2.2 File 類的常用方法

方法聲明功能描述
boolean exists()判定 File  對象對應(yīng)的文件或目錄是否存在
boolean delete()刪除 File  對象對應(yīng)的文件或目錄
boolean createNewFile()當 File 對象對應(yīng)文件不存在時則創(chuàng)建新文件,并且將新建的 File 對象指向新文件
String getName() 返回 File 對象 表示的文件或目錄的名稱
String getPath() 返回 File 對象 表示的文件或目錄的路徑
String getAbsolutePath() 

返回 File 對象 表示的文件或目錄的相對路徑

  • 在 UNIX / Linux 等系統(tǒng)上,如果路徑以 斜線 / 開始,則這個路徑為絕對路徑
  • 在 Widows 等系統(tǒng)上,如果路徑以 盤符 開始,則這個路徑為絕對路徑
String getParentFile() 返回 File 對象 對應(yīng)目錄的父目錄(注:返回的目錄不包含最后一級子目錄)
boolean canRead()判定 File  對象對應(yīng)的文件或目錄是否可讀
boolean canWrite()判定 File  對象對應(yīng)的文件或目錄是否可寫
boolean isFile()判斷 File 對象對應(yīng)的是否是文件
boolean isDirectory()判斷 File 對象對應(yīng)的是否是目錄
boolean isAbsolute()判斷 File 對象對應(yīng)的是否是絕對路徑
long lastModified()返回 1970 年 1 月 1 日 0 時 0 分 0 秒 到文件最后修改時間的 毫秒值
long length()返回文件內(nèi)容的長度(注:單位為 字節(jié))
String[] list()遞歸列出指定目錄的全部內(nèi)容(包括子目錄和文件),只列出名稱
File[] listFiles()返回一個包含 File 對象所有子文件和子目錄的 File 數(shù)組

演示:

public static void main(String[] args) {
    File file = new File("src/test.txt"); // / 也可以作 目錄符號
    System.out.println("文件是否存在:" + file.exists());
    System.out.println("文件名:" + file.getName());
    // ... 具體大家自己可以實踐
}
  • 補充學習: createTempFile() 方法 和 deleteOnExit() 方法

在一些特定情況下,程序需要讀寫一些臨時文件,為此,F(xiàn)ile類提供了createTempFile() 方法 和 deleteOnExit() 方法,用于操作臨時文件。createTempFile() 方法用于創(chuàng)建一個臨時文件,deleteOnExit() 方法在Java虛擬機退出時自動刪除臨時文件。

下面通過一個案例演示這兩個方法的使用:

public static void main(String[] args) throws IOException {
    // 提供臨時文件的前綴和擴展名
    File file = File.createTempFile("itcast-", ".txt");
    file.deleteOnExit();  // java 虛擬機退出時 自動刪除文件 file
    System.out.println("file 是否為文件:" + file.isFile());
    System.out.println("file 的相對路徑:" + file.getPath());
}

2.3 遍歷目錄下的文件

File 類中提供了 list()方法,可以獲取目錄下所有文件和目錄的名稱。獲取目錄下所有文件和目錄名稱后,可以通過這些名稱遍歷目錄下的文件,按照調(diào)用方法的不同,對目錄下的文件遍歷可分為以下3種方式。

  1. 遍歷指定目錄下的所有文件
  2. 遍歷指定目錄下指定擴展名的文件
  3. 遍歷包括子目錄中的文件在內(nèi)的所有文件

下面分別對這3種遍歷方式進行詳細講解。

(1)遍歷指定目錄下的所有文件

File 類的 list()方法可以遍歷指定目錄下的所有文件。下面通過一個案例演示如何使用 list()方法遍歷目錄下的所有文件,如下:

public static void main(String[] args) {
    File file = new File("src/IO");
    if(file.isDirectory()) {
        String[] names = file.list(); // 獲取目錄下所有文件的文件名
        for(String name:names) {
            System.out.println(name);  //輸出文件名
        }
    }
}

(2)遍歷指定目錄下指定擴展名的文件

?? 上述代碼實現(xiàn)了遍歷一個目錄下所有文件的功能,然而有時程序只需要獲取指定類型的文件,如獲取指定目錄下所有擴展名為“.java”的文件。

針對這種需求,F(xiàn)ile類提供了一個重載的 list()方法,該方法接收一個 FilenameFilter 類型的參數(shù)。FilenameFilter 是一個接口,被稱作文件過濾器,其中定義了抽象方法accept()用于依次對指定File的所有子目錄或文件進行迭代。在調(diào)用list()方法時,需要實現(xiàn) FilenameFilter,并在accept()方法中進行篩選,從而獲得指定類型的文件。

下面通過一個案例演示如何遍歷指定目錄下所有擴展名為“.java”的文件,如下:

public static void main(String[] args) {
    File file = new File("src/IO");
    // 創(chuàng)建文件過濾器對象
    FilenameFilter filter = new FilenameFilter() {
        // 實現(xiàn) accept 方法
        @Override
        public boolean accept(File dir, String name) {
            File currFile = new File(dir, name);
            // 如果文件以 .java 結(jié)尾返回true
            if(currFile.isFile() && name.endsWith(".java")){
                return true;
            }
            else  return false;
        }
    };
    if(file.exists()) {
        String[] lists = file.list(); // 獲取目錄下所有文件的文件名
        for(String name:lists) {
            System.out.println(name);  //輸出文件名
        }
    }
}

(3)遍歷包括子目錄下的文件在內(nèi)的所有文件

?? 前面的兩個例子演示的都是遍歷當前目錄下的文件。有時候在一個目錄下,除了文件,還有子目錄,如果想獲取所有子目錄下的文件,list()方法顯然不能滿足要求,這時可以使用File 類提供的另一個方法—— listFiles()。

?? 該方法返回一個File對象數(shù)組,當對數(shù)組中的元素進行遍歷時,如果元素中還有子目錄需要遍歷,則可以遞歸遍歷子目錄。下面通過一個案例演示包括子目錄文件的所有文件的遍歷,如下:

public static void main(String[] args) {
    // 創(chuàng)建一個代表目錄的 File 對象
    File file = new File("src");
    fileDir(file);
}
public static void fileDir(File dir)
{
    File[] files = dir.listFiles(); // 獲得表示目錄下的所有文件數(shù)組
    for(File file :files) // 遍歷所有子目錄和文件
    {
        if(file.isDirectory()){
            fileDir(file); // 如果是目錄則遞歸調(diào)用
        }
        System.out.println(file.getAbsolutePath()); // 獲取文件的絕對路徑
    }
}

2.4 刪除文件及目錄

??在操作文件時,可能會遇到需要刪除一個目錄下某個文件或刪除整個目錄的操作,這時就可以調(diào)用File 類中的 delete() 方法。

public static void main(String[] args) {
    File file = new File("src/IO");
    if(file.exists()){
        System.out.println(file.delete());
    }
}

// 輸出 
false

為啥會輸出 false 呢?

??因為文件刪除失敗了,F(xiàn)ile 類中的 delete() 方法只能刪除一個指定的文件,假如 File 對象代表一個目錄,而且這個目錄下包含子目錄或文件,則 File 類中的 delete() 方法 時不允許刪除整個目錄的。 此時就需要采用遞歸的方法來全部刪除

public static void main(String[] args) {
    File file = new File("src/IO");
    deleteDir(file);
    System.out.println("刪除成功??!");
}

public static void deleteDir(File dir)
{
    if(dir.exists())
    {
        File[] files = dir.listFiles(); // 獲得表示目錄下的所有文件數(shù)組
        for(File file :files) // 遍歷所有子目錄和文件
        {
            if(file.isDirectory()){
                deleteDir(file); // 如果是目錄則遞歸調(diào)用
            }
            else file.delete();// 如果是文件直接刪除
        }
        // 刪除整個目錄下的所有文件之后,就刪除這個目錄
        dir.delete();
    }
}

注意:

  • 刪除目錄是從 Java 虛擬機直接刪除而不放入到回收站,文件一旦被刪除就無法恢復(fù),因此在進行文件刪除操作的時候需要格外小心!??

3. 字節(jié)流

3.1 基本概念

?? 在程序的開發(fā)中,經(jīng)常需要處理設(shè)備之間的數(shù)據(jù)傳輸,而在計算機中,無論是文本,圖片、音頻還是視頻,所有文件都是以二進制(字節(jié))形式存在的。對于字節(jié)的輸入輸出,I/0 系統(tǒng)提供了一系列流,統(tǒng)稱為字節(jié)流。字節(jié)流是程序中最常用的流,根據(jù)數(shù)據(jù)的傳輸方向可將其分為字節(jié)輸入流和字節(jié)輸出流。

?? JDK 提供了兩個抽象類—— InputStream OutputStream ,它們是字節(jié)流的頂級父類,所有的字節(jié)輸入流都繼承 InputStream ,所有的字節(jié)輸出流都繼承 OutputStream 。

字節(jié)流抽象基類

  1. InputStream:這個抽象類是表示字節(jié)輸入流的所有類的超類
  2. OutputStream:這個抽象類是表示字節(jié)輸出流的所有類的超類
  3. 子類名特點:子類名稱都是以其父類名作為子類名的后綴

??注: I/O 流的輸入輸出是相對于 程序而言的

  • InputStream 類常用方法
方法聲明功能描述
int read()從輸入流讀取一字節(jié)(8位), 把它轉(zhuǎn)化位 0 - 255 的整數(shù),并返回這個整數(shù)
int read (byte[ ] b)從輸入流讀取若干字節(jié),把它們保存到參數(shù) b  指定的字節(jié)數(shù)組中,返回的整數(shù)表示讀取的字節(jié)數(shù)
int read (byte[ ] b, int off, int len)從輸入流讀取若干字節(jié),把它們保存到參數(shù) b  指定的字節(jié)數(shù)組中,off指定字節(jié)數(shù)組保存數(shù)據(jù)的起始索引,len 表示讀取的字節(jié)數(shù)
void close()關(guān)閉輸入流并且釋放與其相關(guān)的所有系統(tǒng)資源

上表中的3個 read() 方法都是用來讀數(shù)據(jù)的。其中:

  1. 第一個 read() 方法是從輸入流中逐個讀入字節(jié);
  2. 而第二個和第三個read()方法則可以將若干字節(jié)以字節(jié)數(shù)組的形式一次性讀入,從而提高讀數(shù)據(jù)的效率。在進行 I/O 操作時,當前 I/O 流會占用一定的內(nèi)存,由于系統(tǒng)資源非常寶貴,因此,在I/0操作結(jié)束后,應(yīng)該調(diào)用close()方法關(guān)閉 I/O 流,從而釋放當前 I/O 流 所占的系統(tǒng)資源。
  • OutputStream 類常用方法
方法聲明功能描述
void write(int b)將指定的字節(jié)寫入此文件輸出流,一次寫一個字節(jié)數(shù)據(jù)
void write(byte[] b)將參數(shù) b指定的字節(jié)數(shù)組的所有字節(jié)寫入到此文件輸出流,一次寫一個字節(jié)數(shù)組數(shù)據(jù)
void write(byte[] b, int off, int len)將指定 byte 數(shù)組從偏移量off(起始索引)開始的 len字節(jié)寫入此文件輸出流 
void flush()刷新輸出流并且強制寫出所有緩沖的輸出字節(jié)
void close()關(guān)閉輸出流并且釋放與其關(guān)聯(lián)的所有系統(tǒng)資源

??上表前3個是重載的write()方法,都用于向輸出流寫入字節(jié)。

  1. 其中,第一個write()方法逐個寫入字節(jié);
  2. 后兩個write()方法將若干字節(jié)以字節(jié)數(shù)組的形式一次性寫人,從而提高寫數(shù)據(jù)的效率。
  3. flush()方法用來將當前輸出流緩沖區(qū)(通常是字節(jié)數(shù)組)中的數(shù)據(jù)強制寫入目標設(shè)備,此過程稱為刷新。
  4. close()方法用來關(guān)閉1/0流并釋放與當前1/0流相關(guān)的系統(tǒng)資源。

InputStream OutputStream 這兩個類雖然提供了一系列和讀寫數(shù)據(jù)有關(guān)的方法,但是這兩個類是抽象類,不能被實例化,因此,針對不同的功能, InputStream 類 OutputStream 類提供了不同的子類,形成了體系結(jié)構(gòu),如下圖:

InputStream 體系結(jié)構(gòu)圖:

OutputStream 體系結(jié)構(gòu)圖:

3.2 字節(jié)流讀文件

  • ??InputStream 就是JDK提供的基本輸入流,它是所有輸入流的父類,FileInputStream InputStream 的子類,它是操作文件的字節(jié)輸入流,專門用于讀取文件中的數(shù)據(jù)。因為從文件讀取數(shù)據(jù)是重復(fù)的操作,所以需要通過循環(huán)語句實現(xiàn)數(shù)據(jù)的持續(xù)讀取。

下面通過一個案例實現(xiàn)字節(jié)流對文件數(shù)據(jù)的讀取。在實現(xiàn)案例之前,先做以下操作:

  1. 首先在 Java項目的根目錄下創(chuàng)建文本文件test.txt
  2. 在文件中輸入內(nèi)容“itcast” 并保存
  3. 然后使用字節(jié)輸入流對象讀取 test.txt文本文件

案例代碼:

public static void main(String[] args) throws IOException {
    // 創(chuàng)建一個文件字節(jié)輸入流,并且指定源文件名稱
    FileInputStream in = new FileInputStream("src/IO/test.txt");
    int b = 0; // 定義 int 類型的變量 b,用于 記住每次讀取的 1 字節(jié)
    while(true) {
        b = in.read(); // 變量 b 記住讀取的每一字節(jié)
        if(b == -1){ // 如果讀取的字節(jié) 位 -1,則跳出循環(huán)
            break;
        }
        System.out.println(b + " "); // 否則輸出b
    }
    in.close();
}

// 輸出
105 116 99 97 115 116

由于計算機中的數(shù)據(jù)都是以字節(jié)的形式存在的。在test.txt文件中,字符i、 t、c、a、s、t 各占一字節(jié),所以最終結(jié)果顯示的就是文件test.txt中的6字節(jié)對應(yīng)的十進制數(shù)(即這6個字母的ASCII碼值)。

?? 注意:

  • 有時,在文件讀取的過程中可能會發(fā)生錯誤。例如,由于文件不存在而導(dǎo)致無法讀取。
  • 或者用戶沒有讀取權(quán)限等等。這些錯誤都由Java虛擬機自動封裝成 IOException 異常并拋出。例如,當讀取一個不存在的文件時,控制臺會報告異常信息,

讀取一個不存在的文件時,程序就會有一個潛在的問題。如果文件讀取過程中發(fā)生了 I/O 錯誤,InputStream 就無法正常關(guān)閉,系統(tǒng)資源也無法及時釋放,這樣會造成系統(tǒng)資源浪費

對此,可以使用 try…· finally 語句保證 InputStream 在任何情況下都能夠正確關(guān)閉。修改上述代碼,將讀取文件的代碼放入try語句塊中,將關(guān)閉輸入流的代碼放入finaly語句塊中,具體代碼如下:

public static void main(String[] args) throws Exception {
    InputStream input = null;
    try {
        // 創(chuàng)建一個文件字節(jié)輸入流
        FileInputStream in = new FileInputStream("src/IO/test.txt");
        int b = 0; // 定義 int 類型的變量 b,用于 記住每次讀取的 1 字節(jié)
        while (true) {
            b = in.read(); // 變量 b 記住讀取的每一字節(jié)
            if (b == -1) { // 如果讀取的字節(jié) 位 -1,則跳出循環(huán)
                break;
            }
            System.out.print(b + " "); // 否則輸出b
        }
    } finally {
        if (input != null) {
            input.close();
        }
    }
}

3.3 字節(jié)流寫文件

OutputStream 是JDK提供的基本輸出流,與InputStream類似.

  1. OutputStream是所有輸出流的父類。
  2. OutputStream 是一個抽象類,如果使用此類,則必須先通過子類實例化對象。
  3. OutputStream類有多個子類,其中FileOutputStream子類是操作文件的字節(jié)輸出流,專門用于把數(shù)據(jù)寫入文件。

案例演示:

public static void main(String[] args) throws Exception {
    OutputStream out = new FileOutputStream("src/IO/example.txt");
    String str = "Island1314";
    byte[] b = str.getBytes();
    for(int i = 0; i < b.length; i++){
        out.write(b[i]);
    }
    out.close();
}

由上可知,使用 FileOutputStream 寫數(shù)據(jù)時,程序自動創(chuàng)建了文件 example.txt,并將數(shù)據(jù)寫入example.txt 文件。需要注意的是,如果通過 FileOutputStream 向一個已經(jīng)存在的文件中寫入數(shù)據(jù),那么該文件中的數(shù)據(jù)會被覆蓋。

若希望在已存在的文件內(nèi)容之后追加新內(nèi)容,我們應(yīng)該怎么做:

  • 可使用 FileOutputStream 的構(gòu)造函數(shù) public FileOutputStream(String name,boolean append)
  • 創(chuàng)建文件輸出流以指定的名稱寫入文件,并把append參數(shù)的值設(shè)置為true。如果第二個參數(shù)為true ,則字節(jié)將寫入文件的末尾而不是開頭
public static void main(String[] args) throws Exception {
    OutputStream out = new FileOutputStream("src/IO/example.txt",true);
    String str = "\r\n201314";
    byte[] b = str.getBytes();
    for(int i = 0; i < b.length; i++){
        out.write(b[i]);
    }
    out.close();
}

// 在 example.txt 查看
Island1314
201314

// 解釋:程序通過字節(jié)輸出流對象out向文件example.txt寫入后,并沒有將文件原來的數(shù)據(jù)清空,而是將新寫入的數(shù)據(jù)追加到了文件的末尾。

上面的 \r \n 又是什么意思呢 》 解釋如下:

對于字節(jié)流寫數(shù)據(jù),應(yīng)該如何實現(xiàn)換行

  1. windows:\r\n
  2. linux:\n
  3. mac:\r


需要注意的是:I/O流 在進行數(shù)據(jù)讀寫操作時會出現(xiàn)異常。為了保持代碼的簡潔,在InputStream 讀文件和OutputStream寫文件的程序中都使用了throws關(guān)鍵字將異常拋出。然而一旦遇到 I/O異常,I/O流 close()方法無法得到執(zhí)行,I/O流 對象占用的系統(tǒng)資源將得不到釋放。

因此,為了保證I/O流close()方法 必須執(zhí)行,通常將關(guān)閉 I/O流 的操作寫在 finally代碼塊中。

3.4 字節(jié)流復(fù)制文件

在應(yīng)用程序中,I/O 流通常都是成對出現(xiàn)的,即輸入流和輸出流一起使用。例如:文件的復(fù)制就需要通過輸入流讀取一個文件中的數(shù)據(jù),再通過輸出流將數(shù)據(jù)寫入另一個文件。

下面通過一個案例演示文件內(nèi)容的復(fù)制:

  1. 首先在 src 項目的根目錄下創(chuàng)建 source目錄和 target 目錄,
  2. 然后在 source 目錄中存放 a.png文件,
  3. 最后將 source目錄下的 a.png 復(fù)制到 target 目錄下并重新命名為 b.png。
public static void main(String[] args) throws Exception{
    // 創(chuàng)建一個文件輸入流,用于讀取 sorce 目錄的 a.png 文件
    InputStream in = new FileInputStream("src/source/a.png");

    // 創(chuàng)建一個文件輸出流,用于將讀取數(shù)據(jù)寫入到 target 目錄的 b.png 文件
    OutputStream out = new FileOutputStream("src/target/b.png");

    int len; //用于記住每次讀取的 1 字節(jié)
    // 獲取復(fù)制文件前的系統(tǒng)時間
    long begintime = System.currentTimeMillis();
    while ((len = in.read())!= -1){ // 讀取 1 字節(jié)并且判斷是否讀到文件末尾
        out.write(len); // 將讀取的 1 字節(jié)寫入文件
    }

    // 獲取文件復(fù)制結(jié)束后的時間
    long endtime = System.currentTimeMillis();
    System.out.println("復(fù)制文件所消耗時間:" + (endtime - begintime) + "ms");

    in.close();
    out.close();
}

// 輸出:
復(fù)制文件所消耗時間:6038ms

上述代碼實現(xiàn)了文件的復(fù)制:

  • 通過while循環(huán)將a.png的所有字節(jié)逐個進行復(fù)制。
  • 每循環(huán)一次,就通過調(diào)用FileInputStream的read()方法讀取一字節(jié),
  • 并通過調(diào)用FileOutputStream 的write()方法將該字節(jié)寫入指定文件,直到 len 的值為 -1,表示讀到了文件末尾,結(jié)束循環(huán),完成文件的復(fù)制。
  • 程序運行結(jié)束后,會在命令行窗口打印復(fù)制文件所消耗的時間。
  • 由上可知,程序復(fù)制文件共消耗了6038ms。在復(fù)制文件時,由于計算機性能等各方面原因,會導(dǎo)致復(fù)制文件所消耗的時間不確定,因此每次運行程序的結(jié)果未必相同。

在程序運行結(jié)束后,打開target目錄,發(fā)現(xiàn)source目錄中的 a.png 文件被成功復(fù)制到 target目錄中

注意事項:

上述實現(xiàn)的文件復(fù)制過程是逐字節(jié)讀寫,需要頻繁地操作文件,效率非常低

打個比方:

  • 從北京運送烤鴨到上海,如果有一萬只烤鴨,每次運送一只,就必須運輸一萬次,這樣的效率顯然非常低。為了減少運輸次數(shù),可以先把一批烤鴨裝在車廂中,這樣就可以成批地運送烤鴨,這時的車廂就相當于一個緩沖區(qū)

因此在通過流的方式復(fù)制文件時,為了提高效率,也可以定義一個字節(jié)數(shù)組作為緩沖區(qū)。

  1. 在復(fù)制文件時,可以一次性讀取多個字節(jié)的數(shù)據(jù),并保存在字節(jié)數(shù)組中,然后將字節(jié)數(shù)組中的數(shù)據(jù)一次性寫入文件。
  2. 程序中的緩沖區(qū)就是一塊內(nèi)存,它主要用于暫時存放輸入輸出的數(shù)據(jù),由于使用緩沖區(qū)減少了對文件的操作次數(shù),所以可以提高數(shù)據(jù)的讀寫效率

利用緩沖區(qū)復(fù)制文件,修改代碼如下:

public static void main(String[] args) throws Exception{
    // 創(chuàng)建一個文件輸入流,用于讀取 sorce 目錄的 a.png 文件
    InputStream in = new FileInputStream("src/source/a.png");

    // 創(chuàng)建一個文件輸出流,用于將讀取數(shù)據(jù)寫入到 target 目錄的 b.png 文件
    OutputStream out = new FileOutputStream("src/target/b.png");

    // 以下是用 緩沖區(qū) 讀寫文件
    byte[] buff = new byte[1024]; // 定義一個字節(jié)數(shù)組作緩沖區(qū)

    int len; //用于記住每次讀取的 1 字節(jié)
    // 獲取復(fù)制文件前的系統(tǒng)時間
    long begintime = System.currentTimeMillis();
    while ((len = in.read(buff))!= -1){ // 讀取 1 字節(jié)并且判斷是否讀到文件末尾
        out.write(buff, 0, len); // 將讀取的 1 字節(jié)寫入文件
    }

    // 獲取文件復(fù)制結(jié)束后的時間
    long endtime = System.currentTimeMillis();
    System.out.println("復(fù)制文件所消耗時間:" + (endtime - begintime) + "ms");

    in.close();
    out.close();
}

// 輸出:
復(fù)制文件所消耗時間:8ms

可以看出復(fù)制文件消耗時間明顯減少,說明使用緩沖區(qū)讀寫文件可以有效地提高程序讀寫效率

4. 字符流

4.1 字符流定義及基本用法

?? 前面講解的內(nèi)容都是通過字節(jié)流直接對文件進行讀寫。如果讀寫的文件內(nèi)容是字符,考慮到使用字節(jié)流讀寫字符可能存在傳輸效率以及數(shù)據(jù)編碼問題、此時建議使用字符流。

同字節(jié)流一樣,字符流也有兩個抽象的頂級父類,分別是 Reader類 和 Writer類。

  1. Reader 類是字符輸入流,用于從某個源設(shè)備讀取字符;
  2. Writer類是字符輸出流。用于向某個目標設(shè)備寫入字符。
  3. 在JDK中,Reader 類和Writer 類提供了一系列與讀寫數(shù)據(jù)相關(guān)的方法。

注:字符流 = 字節(jié)流 + 編碼表

Reader 類的常用方法

方法聲明功能描述
int read()以字符為單位讀數(shù)據(jù)
int read(char[] cbuf)將數(shù)據(jù)讀入 char 類型的數(shù)組,并返回數(shù)組長度
int read(char[] cbuf, int off, int len)將數(shù)據(jù)讀入 char 類型的數(shù)組的指定區(qū)間,并返回數(shù)組長度
void close()關(guān)閉數(shù)據(jù)流
long transferTo(Writer out)將數(shù)據(jù)之間讀入字符輸出流

Writer 類的常用方法

方法聲明功能描述
void write(int c)以字符為單位寫數(shù)據(jù)
void write(char[] cbuf)將 char 類型的數(shù)組中的數(shù)據(jù)寫出
void write(char[] cbuf, int off, int len)將 char 類型的數(shù)組中指定區(qū)間的數(shù)據(jù)寫出
void write(String str)將 String 類型的數(shù)據(jù)寫出
void write(String str, , int off, int len)將 String 類型中指定區(qū)間的數(shù)據(jù)寫出
void flush()強制將緩沖區(qū)的數(shù)據(jù)同步到輸出流 (刷新流),之后還可以繼續(xù)寫數(shù)據(jù)
void close()關(guān)閉數(shù)據(jù)流

 Reader 類 Writer 類作為字符流的頂級父類,也有許多子類,形成了體系結(jié)構(gòu),分別如下:

Reader 體系結(jié)構(gòu)圖:

Writer 體系結(jié)構(gòu)圖:

?? 在上面我們可以看到字符流的繼承關(guān)系和字節(jié)流的繼承關(guān)系類似,Reader 類 和 Writer 類的很多子類都是成對出現(xiàn)。例如:

  1. FileReaderFileWriter 用于讀寫文件
  2. BufferedReaderBufferedWriter 是具有緩沖功能的字符流,使用他們可以提高讀寫效率

4.2 字符流讀文件

??在程序開發(fā)中,經(jīng)常需要對文本文件的內(nèi)容進行讀取。如果想從文件中直接讀取字符,便可以使用字符輸入流 FileReader,通過它可以從關(guān)聯(lián)的文件中讀取一個或一組字符。

下面通過一個案例演示如何使用 FileReader 讀取文件中的字符:

  1. 首先新建文本文件 test.txt 并在其中輸入字符 “itcast”
  2. 然后創(chuàng)建字符輸入流 FileReader對象以讀取 reader.txt文件中的內(nèi)容
public static void main(String[] args) throws Exception {
    // 創(chuàng)建一個 FileReader 對象,用來讀取文件字符
    FileReader reader = new FileReader("src/IO/test.txt");
    int ch; // 用于記錄讀取的字符
    while((ch = reader.read()) != -1){ // 循環(huán)判斷是否讀到文件末尾
        System.out.print((char) ch); // 不是文件末尾就打印字符
    }
    reader.close(); // 關(guān)閉字符輸入流,釋放資源
}


// 輸出
itcast

注:FileReader對象的 read() 方法返回的是 int 類型的值,如果想獲得字符,就必須進行強制類型轉(zhuǎn)換。

4.3 字符流寫文件

??‍??上面講解了字符流對文本文件內(nèi)容的讀取?,F(xiàn)在講解通過字符流向文本文件中寫入內(nèi)容,此時需要使用FileWriter類,該類可以一次向文件中寫人一個或一組字符。

下面通過一個案例演示如何使用  FileWriter 將字符寫入文件

public static void main(String[] args) throws Exception {
    // 創(chuàng)建一個 FileWriter 對象,用于向文件寫入數(shù)據(jù)
    FileWriter writer = new FileWriter("src/IO/example.txt");
    String str = "IsLand1314";
    writer.write(str); // 將字符數(shù)據(jù)寫入到文本文件中
    writer.write("\r\n"); //輸出換行
    writer.close();
}

注意:

 FileWriterFileOutputStream 一樣,如果指定的文件不存在,就會先創(chuàng)建文件,再寫入數(shù)據(jù);如果文件存在,則原文件內(nèi)容會被覆蓋。如果想在文件末尾追加數(shù)據(jù),同樣需要調(diào)用重載的構(gòu)造方法,將上面第三行代碼修改為:

FileWriter writer = new FileWriter("src/IO/example.txt", true);

再次運行程序就可以在文件中實現(xiàn)追加的功能

4.4 數(shù)據(jù)編碼解碼問題

由于字節(jié)流操作中文不是特別的方便,所以Java就提供字符流

  • 字符流 = 字節(jié)流 + 編碼表

中文的字節(jié)存儲方式

  • 用字節(jié)流復(fù)制文本文件時,文本文件也會有中文,但是沒有問題,原因是最終底層操作會自動進行字節(jié)拼接成中文,如何識別是中文的呢?
  • 漢字在存儲的時候,無論選擇哪種編碼存儲,第一個字節(jié)都是負數(shù)
函數(shù)聲明功能描述
byte[] getBytes()使用平臺的默認字符集將該 String編碼為一系列字節(jié)
byte[] getBytes(String charsetName)使用指定的字符集將該 String編碼為一系列字節(jié)
String(byte[] bytes)使用平臺的默認字符集解碼指定的字節(jié)數(shù)組來創(chuàng)建字符串
String(byte[] bytes, String charsetName)通過指定的字符集解碼指定的字節(jié)數(shù)組來創(chuàng)建字符串

代碼演示:

public static void main(String[] args) throws UnsupportedEncodingException {
    //定義一個字符串
    String s = "中國";

    //byte[] bys = s.getBytes(); //[-28, -72, -83, -27, -101, -67]
    //byte[] bys = s.getBytes("UTF-8"); //[-28, -72, -83, -27, -101, -67]
    byte[] bys = s.getBytes("GBK"); //[-42, -48, -71, -6]
    System.out.println(Arrays.toString(bys));

    //String ss = new String(bys);
    //String ss = new String(bys,"UTF-8");
    String ss = new String(bys,"GBK");
    System.out.println(ss);
}

5. 轉(zhuǎn)換流

?? 前面提到I/0流分為字節(jié)流和字符流,字節(jié)流和字符流之間可以進行轉(zhuǎn)換。JDK提供了兩個類用于將字節(jié)流轉(zhuǎn)換為字符流,分別是 InputStreamReader OutputStreamReader。

InputStreamReader:是從字節(jié)流到字符流的橋梁,父類是 Reader

  • 它讀取字節(jié),并使用指定的編碼將其解碼為字符
  • 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集

OutputStreamReader:是從字符流到字節(jié)流的橋梁,父類是 Writer

  • 是從字符流到字節(jié)流的橋梁,使用指定的編碼將寫入的字符編碼為字節(jié)
  • 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集


通過 InputStreamReaderOutputStreamReader 將字節(jié)流轉(zhuǎn)換為字符流,可以提高文件的讀寫效率

方法聲明功能描述
InputStreamReader(InputStream in)使用默認字符編碼創(chuàng)建InputStreamReader對象
InputStreamReader(InputStream in,String chatset)使用指定的字符編碼創(chuàng)建InputStreamReader對象
OutputStreamWriter(OutputStream out)使用默認字符編碼創(chuàng)建OutputStreamWriter對象
OutputStreamWriter(OutputStream out,String charset)使用指定的字符編碼創(chuàng)建OutputStreamWriter對象

下面通過一個案例演示如何將字節(jié)流轉(zhuǎn)為字符流

  1. 首先.在src項目的根目錄下新建文本文件 test.txt
  2. 并在文件中輸入“Island1314”
  3. 其次,在sre文件夾中創(chuàng)建一個類,在類中創(chuàng)建字節(jié)輸入流 FileInputStream對象讀取src.txt文件中的內(nèi)容,并將字節(jié)輸入流轉(zhuǎn)換成字符輸入流。
  4. 再次,創(chuàng)建一個字節(jié)輸出流對象,并指定目標文件為des.txt
  5. 最后,將字節(jié)輸出流轉(zhuǎn)換成字符輸出流將字符輸出到文件中
public static void main(String[] args) throws Exception {
    // 創(chuàng)建字節(jié)輸入流 in ,并且指定源文件 test.txt
    FileInputStream in = new FileInputStream("src/IO/test.txt");
    // 將字節(jié)輸入流 in 轉(zhuǎn)化為 字符輸入流 isr
    InputStreamReader isr = new InputStreamReader(in);

    // 創(chuàng)建字節(jié)輸出流 out ,并且指定源文件 des.txt
    FileOutputStream out = new FileOutputStream("src/IO/des.txt");
    // 將字節(jié)輸出流 out 轉(zhuǎn)化為 字符輸出流 osw
    OutputStreamWriter osw = new  OutputStreamWriter(out);

    int ch; // 定義一個變量用于記錄讀取的字符
    while((ch = isr.read()) != -1) // 循環(huán)判斷是否讀到文件末尾
    {
        osw.write(ch);
    }
    isr.close(); // 關(guān)閉字符輸入流,節(jié)省資源
    osw.close(); // 關(guān)閉字符輸出流,節(jié)省資源
}

6. 緩沖流

6.1 字節(jié)緩沖流

  1. BufferedOutputStream:該類實現(xiàn)緩沖輸出流.通過設(shè)置這樣的輸出流,應(yīng)用程序可以向底層輸出流寫入字節(jié),而不必為寫入的每個字節(jié)導(dǎo)致底層系統(tǒng)的調(diào)用
  2. BufferedInputStream:創(chuàng)建BufferedInputStream將創(chuàng)建一個內(nèi)部緩沖區(qū)數(shù)組.當從流中讀取或跳過字節(jié)時,內(nèi)部緩沖區(qū)將根據(jù)需要從所包含的輸入流中重新填充,一次很多字節(jié)
  3. 字節(jié)流緩沖區(qū)的核心優(yōu)勢就是一次讀取多個字節(jié)數(shù)據(jù),從而減少硬盤操作子樹

構(gòu)造方法:

BufferedOutputStream(OutputStream out)創(chuàng)建字節(jié)緩沖輸出流對象
BufferedInputStream(InputStream in)創(chuàng)建字節(jié)緩沖輸入流對象
public static void main(String[] args) throws IOException {
    //字節(jié)緩沖輸出流:BufferedOutputStream(OutputStream out)
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("src/IO/test.txt"));
    //寫數(shù)據(jù)
    bos.write("hello\r\n".getBytes());
    bos.write("world\r\n".getBytes());
    //釋放資源
    bos.close();

    //字節(jié)緩沖輸入流:BufferedInputStream(InputStream in)
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src/IO/test.txt"));

    //一次讀取一個字節(jié)數(shù)據(jù)
//        int by;
//        while ((by=bis.read())!=-1) {
//            System.out.print((char)by);
//        }

    //一次讀取一個字節(jié)數(shù)組數(shù)據(jù)
    byte[] bys = new byte[1024];
    int len;
    while ((len=bis.read(bys))!=-1) {
        System.out.print(new String(bys,0,len));
    }

    //釋放資源
    bis.close();
}

6.2 字符緩沖流

  1. BufferedWriter:將文本寫入字符輸出流,緩沖字符,以提供單個字符,數(shù)組和字符串的高效寫入,可以指定緩沖區(qū)大小,或者可以接受默認大小。默認值足夠大,可用于大多數(shù)用途
  2. BufferedReader:從字符輸入流讀取文本,緩沖字符,以提供字符,數(shù)組和行的高效讀取,可以指定緩沖區(qū)大小,或者可以使用默認大小。 默認值足夠大,可用于大多數(shù)用途
BufferedWriter(Writer out)創(chuàng)建字符緩沖輸出流對象
BufferedReader(Reader in)創(chuàng)建字符緩沖輸入流對象
public static void main(String[] args) throws IOException {

    //創(chuàng)建字符緩沖輸出流
    BufferedWriter bw = new BufferedWriter(new FileWriter("src/IO/test.txt"));

    //寫數(shù)據(jù)
    for (int i = 0; i < 10; i++) {
        bw.write("hello" + i);
        //bw.write("\r\n");
        bw.newLine();
        bw.flush();
    }

    //釋放資源
    bw.close();

    //創(chuàng)建字符緩沖輸入流
    BufferedReader br = new BufferedReader(new FileReader("src/IO/test.txt"));

    String line;
    while ((line=br.readLine())!=null) {
        System.out.println(line);
    }

    br.close();
}

7. 序列化反序列化

?? 程序在運行過程中,數(shù)據(jù)都保存在Java對象(內(nèi)存)中,但很多情況下還需要將一些數(shù)據(jù)永久保存到磁盤上。為此,Java 提供了對象序列化機制,可以將對象中的數(shù)據(jù)保存到磁盤。

對象序列化(serialize)是指將一個Java對象轉(zhuǎn)換成一個 I/O流 的字節(jié)序列的過程

  1. 對象序列化機制可以使內(nèi)存中的Java對象轉(zhuǎn)換成與平臺無關(guān)的二進制流,
  2. 通過編寫程序,既可以將這種二進制流持久地保存在磁盤上,
  3. 又可以通過網(wǎng)絡(luò)將其傳輸?shù)搅硪粋€網(wǎng)絡(luò)節(jié)點。

?? 其他程序在獲得了二進制流后,還可以將二進制流恢復(fù)成原來的Java對象,這種將 I/O流 中的字節(jié)序列恢復(fù)為Java對象的過程稱為 反序列化(deserialize)。

?? 如果想讓某個對象支持序列化機制,那么這個對象所屬的類必須是可序列化的。在Java中,可序列化的類必須實現(xiàn) SerializableExternalizable 兩個接口之一。

Serializable 接口或 Externalizable 接口實現(xiàn)序列化機制的主要區(qū)別

Serializable 接口Externalizable 接口
系統(tǒng)自動存儲必要的信息由程序員自己決定要存儲的信息
Java 內(nèi)部支持,易于實現(xiàn),只需實現(xiàn)該接口即可,不需要其他代碼支持該接口只提供了兩個抽象方法,實現(xiàn)該接口時必須重寫這兩個抽象方法
性能較差性能較好

?? 與實現(xiàn) Serializable  接口相比,雖然實現(xiàn) Externalizable 接口可以帶來性能上的一定提升,但由于后者需要實現(xiàn)兩個抽象方法,所以將導(dǎo)致編程的復(fù)雜度提高。

  • 在實際開發(fā)時,大部分情況下使用Serializable 接口的方式實現(xiàn)對象序列化。

??使用Serializable 接口實現(xiàn)對象序列化非常簡單,只需要讓目標類實現(xiàn) Serializable 接口即可,無須實現(xiàn)任何方法。例如,自定義Person類,讓Person類實現(xiàn) Serializable接口,如下:

public class Person implements Serializable{
    // 為該類指定 serialVersionUID 變量值
    private static final long serialVersionUID = 1L;
    // 聲明變量
    private int id;
    private String name;
    private int age;
    //... 此處省略各屬性的 gettter 和 setter 方法
}

?? 在上述代碼中,Person類實現(xiàn)了 Serializable接口,并指定了 serialVersionUID變量值,該屬性的值的作用是標識Java類的序列化版本。如果不顯式定義 serialVersionUID變量值,那么serialVersionUID屬性的值將由 Java 虛擬機 根據(jù)類的相關(guān)信息計算得出

補充知識:serialVersionUID

?? serialVersionUID適用于Java的對象序列化機制。簡單來說,Java的對象序列化機制是通過判斷類的 serialVersionUID 來驗證版本一致性的。在進行反序列化時,Java虛擬機會把字節(jié)流中的 serialVersionUID 與本地相應(yīng)實體類的 serialVersionUID 進行比較。如果相同,就認為是一致的,可以進行反序列化;否則就會拋出序列化版本不一致的異常。

  • 因此,為了在反序列化時確保序列化版本的兼容性,最好在每一個要序列化的類中加入 private static final long serialVersionUID 的變量值,具體數(shù)值可自定義,默認是1L。
  • 如果不顯式指定 serialVersionUID 的值,系統(tǒng)可以根據(jù)類名、接口名、成員方法及屬性等生成一個64位的哈希值,將這個哈希值作為serialVersionUID的值。
  • 定義了serialVersionUID的值,如果serialVersionUID所屬類的某個對象被序列化,即使該對象對應(yīng)的類被修改了,該對象也依然可以被正確地反序列化。

8. 小結(jié)

本章主要介紹了 I/O流 的相關(guān)知識。

?? 包括File類,包括創(chuàng)建File對象、File 類的常用方法、遍歷目錄下的文件和刪除文件及目錄;字節(jié)流,包括字節(jié)流的概念、字節(jié)流讀文件、字節(jié)流寫文件和文件的復(fù)制;字符流,包括字符流的定義及基本用法、字符流讀文件和字符流寫文件;轉(zhuǎn)換流的使用;序列化和反序列化。通過本章的學習,讀者應(yīng)該了解 I/O 流,并且熟練掌握了 I/O 流的相關(guān)知識。

補充:字節(jié)流與字符流區(qū)別

字節(jié)流是IO中最基礎(chǔ)的形式,它以字節(jié)(8位)為單位進行數(shù)據(jù)傳輸,適用于處理所有類型的數(shù)據(jù),包括文本、圖片、音頻和視頻等二進制數(shù)據(jù)。在Java中,字節(jié)流的基類是InputStream和OutputStream。字節(jié)流在操作時通常不會使用緩沖區(qū),直接與文件本身進行操作,這意味著每次調(diào)用read方法都可能伴隨著一次磁盤IO,因此效率相對較低。為了提高效率,可以使用如BufferedInputStream和BufferedOutputStream這樣的緩沖字節(jié)流。

字符流則是以Unicode碼元(16位)為單位進行數(shù)據(jù)傳輸,主要用于處理文本數(shù)據(jù)。字符流在處理數(shù)據(jù)時會涉及字符編碼的轉(zhuǎn)換,如UTF-8或GBK等。在Java中,字符流的基類是Reader和Writer。字符流在輸出前會完成Unicode碼元序列到相應(yīng)編碼方式的字節(jié)序列的轉(zhuǎn)換,并使用內(nèi)存緩沖區(qū)來存放轉(zhuǎn)換后的字節(jié)序列,等待都轉(zhuǎn)換完畢再一同寫入磁盤文件中。

主要區(qū)別在于:

  • 字節(jié)流操作的基本單元為字節(jié),而字符流操作的基本單元為Unicode碼元。

  • 字節(jié)流不使用緩沖區(qū),字符流使用緩沖區(qū)。

  • 字節(jié)流可以處理任何類型的數(shù)據(jù),字符流主要處理文本數(shù)據(jù)。

  • 字節(jié)流與文件直接操作,字符流在操作時使用緩沖區(qū)。

到此這篇關(guān)于Java中I/O操作的文章就介紹到這了,更多相關(guān)Java I/O操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis-Plus更新字段為null的三種解決方案

    MyBatis-Plus更新字段為null的三種解決方案

    這篇文章主要為大家詳細介紹了MyBatis-Plus更新字段為null的三種解決方案,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-10-10
  • Fastjson 常用API介紹及下載地址(推薦)

    Fastjson 常用API介紹及下載地址(推薦)

    Fastjson是一個Java語言編寫的高性能功能完善的JSON庫。接下來通過本文給大家分享Fastjson 常用API介紹及下載地址,感興趣的朋友一起看看吧
    2017-11-11
  • Springboot RestTemplate 簡單使用解析

    Springboot RestTemplate 簡單使用解析

    這篇文章主要介紹了Springboot RestTemplate 簡單使用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • Springboot實現(xiàn)Excel批量導(dǎo)入數(shù)據(jù)并保存到本地

    Springboot實現(xiàn)Excel批量導(dǎo)入數(shù)據(jù)并保存到本地

    這篇文章主要為大家詳細介紹了Springboot實現(xiàn)Excel批量導(dǎo)入數(shù)據(jù)并將文件保存到本地效果的方法,文中的示例代講解詳細,需要的可以參考一下
    2022-09-09
  • Mybatis的七種傳參方式示例全解析

    Mybatis的七種傳參方式示例全解析

    MyBatis提供了七種傳參方式,包括順序傳遞參數(shù)、使用@Param注解命名傳參、使用Map傳遞多個參數(shù)、使用JavaBean對象傳參、使用JSON對象直接傳參、集合類型傳參以及對象中包含集合屬性的傳參,每種方式都有其適用場景和優(yōu)勢,感興趣的朋友一起看看吧
    2026-01-01
  • SpringBoot MDC全鏈路調(diào)用日志跟蹤實現(xiàn)詳解

    SpringBoot MDC全鏈路調(diào)用日志跟蹤實現(xiàn)詳解

    這篇文章主要為大家介紹了SpringBoot MDC全鏈路調(diào)用日志跟蹤實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • java中常用的阻塞隊列與非阻塞隊列詳解

    java中常用的阻塞隊列與非阻塞隊列詳解

    這篇文章主要介紹了java中常用的阻塞隊列與非阻塞隊列用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • MyBatis中SQL映射與動態(tài)查詢的技巧分享

    MyBatis中SQL映射與動態(tài)查詢的技巧分享

    SQL映射文件是MyBatis框架中用于定義數(shù)據(jù)庫操作的XML文件,它與應(yīng)用程序的數(shù)據(jù)訪問層進行交互,將Java對象與數(shù)據(jù)庫表之間的映射關(guān)系進行配置,并提供了執(zhí)行SQL語句的方式,本文給大家介紹了MyBatis中SQL映射與動態(tài)查詢的技巧,需要的朋友可以參考下
    2025-09-09
  • springboot+vue實現(xiàn)SSE服務(wù)器發(fā)送事件的示例

    springboot+vue實現(xiàn)SSE服務(wù)器發(fā)送事件的示例

    本文介紹了使用Spring Boot和Vue實現(xiàn)服務(wù)器發(fā)送事件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-01-01
  • Java遠程連接Linux服務(wù)器并執(zhí)行命令及上傳文件功能

    Java遠程連接Linux服務(wù)器并執(zhí)行命令及上傳文件功能

    這篇文章主要介紹了Java遠程連接Linux服務(wù)器并執(zhí)行命令及上傳文件功能,本文是小編整理的代碼筆記,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-05-05

最新評論

黔江区| 漳平市| 马关县| 高雄市| 东莞市| 红桥区| 岱山县| 克山县| 磐安县| 巴南区| 宁都县| 封丘县| 民乐县| 武城县| 济阳县| 辽阳市| 沐川县| 城市| 辰溪县| 高要市| 炎陵县| 清涧县| 正镶白旗| 英超| 友谊县| 宁明县| 广丰县| 马尔康县| 祁阳县| 商洛市| 桐梓县| 新野县| 化德县| 澎湖县| 湘阴县| 辛集市| 新田县| 古浪县| 容城县| 竹山县| 广东省|