Java(8)I/O

Javalove劉志先發表於2020-11-26

目錄

一、File類

1、File類概述

  • java.io.File類:一個java.io.File類的物件,表示檔案和檔案目錄路徑(就是資料夾)
  • File 能新建、刪除、重新命名檔案和目錄,但 File 不能訪問檔案內容本身。如果需要訪問檔案內容本身,則需要使用輸入/輸出流。
  • 想要在Java程式中表示一個真實存在的檔案或目錄,那麼必須有一個File對 象,但是Java程式中的一個File物件,可能沒有一個真實存在的檔案或目錄。

  • 經典應用場景:File物件可以作為引數傳遞給流的構造器。

2、File類例項化

  • 構造器
構造器 描述
File(String pathname) 路徑名稱來建立
File(String parent, String child) 上層目錄路徑+檔名來建立
File(File parent, String child) 上層檔名+檔名來建立
File(URI uri) uri來建立
  • 路徑

    • 絕對路徑:是一個固定的路徑,從碟符開始
    • 相對路徑:是相對於某個位置開始。在IDEA中是相對於當前的module
  • 路徑分隔符

    • windows和DOS系統預設使用“\”來表示
    • UNIX和URL使用“/”來表示
    • Java程式支援跨平臺執行,因此路徑分隔符要慎用。為了解決這個隱患,File類提供了一個常量:public static final String separator,根據作業系統,動態的提供分隔符。
    • 舉例
    File file1 = new File("d:\\atguigu\\info.txt");
    
    File file2 = new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");
    
    File file3 = new File("d:/atguigu");
    

3、File類常用方法

  • **獲取
方法 描述
getAbsolutePath() 獲取絕對路徑
getPath() 獲取路徑
getName() 獲取名
getParent() 獲取上層檔案目錄路徑。若無,返回null
length() 獲取檔案長度(即:位元組數)。不能獲取目錄的長度。
lastModified() 獲取最後一次的修改時間,毫秒值
下面兩個是針對目錄的
public String[] list() 獲取指定目錄下的所有檔案或者檔案目錄的名稱陣列
public File[] listFiles() 獲取指定目錄下的所有檔案或者檔案目錄的File陣列
  • 重新命名

public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑。(實際上就是把file1的內容複製到file2,並把file1刪除)

對於 file1.renameTo(file2)要求:file1存在,file2不存在

  • 判斷
方法 描述
isDirectory() 判斷是否是檔案目錄
isFile() 判斷是否是檔案
exists() 判斷是否存在
canRead() 判斷是否可讀
canWrite() 判斷是否可寫
isHidden() 判斷是否隱藏
  • 建立和刪除
方法 描述 注意事項
public boolean createNewFile() 建立檔案 若檔案存在,則不建立,返回false
public boolean mkdir() 建立檔案目錄 如果此檔案目錄存在,就不建立;
如果此檔案目錄的上層目錄不存在,也不建立
public boolean mkdirs() 建立檔案目錄 如果上層檔案目錄不存在,一併建立
public boolean delete() 刪除檔案或者資料夾 Java中的刪除不走回收站
要刪除的檔案目錄內不能包含檔案或檔案目錄

如果你建立檔案或者 檔案 目錄沒有寫碟符路徑 , 那麼 ,預設在專案路徑下。

二、IO流的原理

1、IO流的原理

  • I/O是input/output的縮寫,IO技術用於裝置之間的資料傳輸。(如。讀/寫檔案、網路通訊
  • Java程式中,資料的輸入/輸出操作以“流(stream)” 的方式進行。
  • java.io包下提供了各種“流”類和介面,用以獲取不同種類的資料,並通過標準的方法輸入或輸出資料。

2、input和output的理解

  • 首先對於入和出,我們是站在程式的角度來說的,想象自己身處程式內部。
  • input:磁碟、光碟等儲存裝置的資料----->程式、記憶體
  • output:程式、記憶體中的資料----->磁碟、光碟等儲存裝置

三、IO流的分類

1、分類

  • √√√按操作的資料單位不同分為:位元組流(8bit)、字元流(16bit)。位元組流適合操作圖片、視訊等檔案,字元流適合操作文字檔案。

  • 按資料流的流向不同分為:輸入流、輸出流。

  • 流的角色不同分為:**節點流、處理流。

    • 節點流:直接從資料來源或目的地讀寫資料。也叫檔案流

    • 處理流:不直接連線到資料來源或目的地,而是“連線”在已存 在的流(節點流或處理流)之上,通過對資料的處理為程式提 供更為強大的讀寫功能

2、圖示

3、四個抽象基類

抽象基類 位元組流 字元流
輸入流 InputStream Reader
輸出流 OutputStream Writer

4、IO流體系

四、FileReader和FileWriter

1、IDEA中單元測試方法和main()下相對路徑對比

  • 單元測試方法下的相對路徑是:相較於當前module而言
  • main()下的相對路徑:相較於當前工程而言

2、使用FileReader讀入資料

  • 最初的程式碼實現
public void test1() throws IOException {
        //1.例項化File類,指明要操作的物件.這一步的目的是建立硬碟中的檔案和Java中類的對應關係.
        File file = new File("hello1.txt");

        //2.提供具體的流.引數的作用就是幫助我們並連線上檔案這個"大水庫"
        FileReader fileReader = new FileReader(file);

        //3.用流讀取到記憶體
        //read():返回讀入的字元,是int需要轉換為char.到了檔案結尾返回-1
        int read = fileReader.read();
        while (read != -1) {
            System.out.print((char) read);
            read = fileReader.read();
        }

        //4.關閉流
        fileReader.close();
    }
    //整個過程結合圖示去理解很合理
  • 改進後的程式碼實現
	/*
    優化:
        1.第三部可以在語法上的優化,但是效率其實是一樣的
        2.為了保證關閉操作一定執行,使用try-catch-finally
        3.讀入的檔案一定要存在,否則會出現:FileNotFoundException
    */
public void test2() {

        FileReader fileReader = null;
        try {
            File file = new File("hello1.txt");

            fileReader = new FileReader(file);

            //改進1
            int read;
            while ((read = fileReader.read()) != -1){
                System.out.print((char) read);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null)
                    fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  • 使用緩衝流改進這個是用的最多的★★★★★)
//使用陣列
char[] charBuffer = new char[5];
int len;//記錄每次讀入到charBuffer陣列中的字元個數
while ((len = fileReader.read(charBuffer)) != -1){
    for (int i = 0; i < len; i++) {//這裡要用len(讀取的字元數)二不是陣列的長度
        System.out.print(charBuffer[i]);
    }
}

//當然for迴圈也可以換位String的構造器來把字串陣列轉換為String
String string = new String(charBuffer, 0, len);
System.out.print(string);

3、使用FileWriter寫出資料

  • 程式碼實現
File file = new File("hello2.txt");
FileWriter fw = new FileWriter(file);
fw.write("i have a dream!");
fw.close();
//最後用try-catch處理一下異常,上面的步驟更清晰一些
  • 說明
    • 輸出時,File可以不存在,不會報異常。
    • File對應的硬碟的檔案如果不存在,自動建立
    • File對應的硬碟的檔案如果存在
      • 如果流使用的構造器是FileWriter(file, false)/FileWriter(file),對原有的檔案進行覆蓋
      • 如果流使用的構造器是FileWriter(file, true),對原有的檔案進行追加

4、使用FileReader和FileWriter複製文字檔案

  • 程式碼實現
public void test5() throws IOException {
        File srcFile = new File("hello2.txt");
        File destFile = new File("hello3.txt");

        FileReader fr = new FileReader(srcFile);
        FileWriter fw = new FileWriter(destFile);

        char[] charBuffer = new char[5];
        int len;
        while ((len = fr.read(charBuffer)) != -1) {
            fw.write(charBuffer, 0, len);//和用String來取是類似的★★★★★
        }

        fw.close();
        fr.close();
}
//最後用try-catch處理一下異常,上面的步驟更清晰一些

5、使用FileReader和FileWriter不能處理圖片的複製的測試

  • 當把hello.txt文字檔案改為圖片檔案時,發現程式碼是可以正常執行,但是複製結果並不對,新圖片打不開。
  • 這是因為,圖片是用位元組來儲存的。用字元流來處理顯然不行。

五、FileInputStream和FileOutputStream

1、用FileInputStream和FileOutputStream處理文字檔案會怎樣?

  • 結論
    • 輸出到控制檯時:英文不亂碼,中文可能會亂碼
    • 單純複製,而不在記憶體層面檢視:不會亂碼,是可以的。
  • 解釋
    • 對於英文,utf-8和gbk都是用一個位元組(4bit位)來存一個字母,因此每個字母都是完完整整的存入byte陣列,從而能完整的複製過去。
    • 對於中文,utf-8中用的是三個位元組來存一個漢字,那麼位元組陣列中的資料在輸出時,不確定在哪裡截斷,就會出現一部分字的亂碼。

2、確定使用字元流還是位元組流

  • 對於文字檔案(.txt, .java, .cpp),使用字元流
  • 對於非文字檔案(.jpg, .mp3, .mp4, .avi, .doc, .ppt...),使用位元組流

3、用FileInputStream和FileOutputStream複製圖片

  • 同“使用FileReader和FileWriter複製文字檔案”,只要
    • 使用FileInputStream和FileOutputStream
    • 把陣列改為byte陣列

六、緩衝流

1、緩衝流有哪些

BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

2、作用

  • 提高讀寫速度

3、原因

  • 在使用這些流類時,會建立一個內部緩衝區陣列,預設使用8192個位元組(8Kb)的緩衝區。
  • 當讀取資料時,資料按塊讀入緩衝區,其後的讀操作則直接訪問緩衝區
  • 當使用BufferedInputStream讀取位元組檔案時,BufferedInputStream會一次性從檔案中讀取8192個(8Kb),存在緩衝區中,直到緩衝區裝滿了,才重新從檔案中讀取下一個8192個位元組陣列。
  • 向流中寫入位元組時,不會直接寫到檔案,先寫到緩衝區中直到緩衝區寫滿, BufferedOutputStream才會把緩衝區中的資料一次性寫到檔案裡。
  • 使用方法 flush()可以強制將緩衝區的內容全部寫入輸出流。
  • 如果是帶緩衝區的流物件的close()方法,不但會關閉流,還會在關閉流之前刷 新緩衝區,關閉後不能再寫出。
    • 填坑:自己寫程式碼的時候忘記關閉流操作,導致複製的圖片打不開的原因就是,沒有關閉流,緩衝區內還有一部分資料沒能複製過去。

4、使用緩衝流複製圖片

public void test() throws IOException {
        //1.建立File
        File srcFile = new File("img1.png");
        File destFile = new File("img2.png");

        //2.建立流
        //2.1建立檔案流
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        //2.2建立位元組流
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //3.複製
        byte[] bytes = new byte[10];
        int len;
        while ((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }

        //4.關閉流
        bis.close();
        bos.close();
}
  • 關閉外層的流的同時,會自動關閉內層的流。所以只寫外層的關閉操作就可以。

5、使用緩衝流複製文字檔案

public void test1() throws IOException {
        //1.建立檔案和流
        BufferedReader br = new BufferedReader(new FileReader(new File("hello1.txt")));
        BufferedWriter bw = new BufferedWriter(new FileWriter(new File("hello4.txt")));

//        //2.複製
//        char[] chars = new char[10];
//        int len;
//        while ((len = br.read(chars)) != -1) {
//            bw.write(chars, 0, len);
//        }


        // 複製:用String來實現★★★★★★★★★★★
        String data;//但是是不帶換行的,可以用一以下兩種方法實現
        while ((data = br.readLine()) != null) {
//          //方法一★★★★★★★★
//            bw.write(data + "\n");
            //方法二★★★★★★★★
            bw.write(data);
            bw.newLine();
        }

        //3.關閉
        br.close();
        bw.close();
    }

6、練習:統計文字每個字元出現次數

七、轉換流

1、什麼是轉換流

  • 轉換流提供了在位元組流和字元流之間的轉換
  • 轉換流屬於字元流
  • Java API提供了兩個轉換流
    • InputStreamReader:將InputStream轉換為Reader
      • 構造器一:public InputStreamReader(InputStream in)預設使用utf-8字符集
      • 構造器二:public InputSreamReader(InputStream in,String charsetName)可以自己選擇字符集。
    • OutputStreamWriter:將Writer轉換為OutputStream
      • 構造器和上面類似
  • 位元組流中的資料都是字元時,轉成字元流操作更高效。
  • 很多時候我們使用轉換流來處理檔案亂碼問題。實現編碼和解碼的功能。

2、編碼與解碼

  • 編碼:位元組、位元組陣列--->字元陣列、字串
  • 解碼:字元陣列、字串--->位元組、位元組陣列

3、字符集

  • 什麼是編碼表:計算機只能識別二進位制資料,早期由來是電訊號。為了方便應用計算機,讓它可以識 別各個國家的文字。就將各個國家的文字用數字來表示,並一一對應,形成一張表。 這就是編碼表。
  • 常見編碼表
按照地區輔助記憶 編碼表 描述
美國 ASCII 一個位元組的7位來表示所有英文和符號
歐洲 ISO8859-1 一個位元組的8位表示所有歐洲語言的字母
中國 GB2312
GBK
最多兩個位元組編碼所有漢字
升級版,加入了更多的漢字
國際通用 Unicode
UTF-8
Unicode編碼是對UTF-8/16的統稱
1-4個位元組表示人類所有文字

4、轉換流的作用示意圖

5、練習題

  • 綜合使用:將文字檔案從utf-8轉換為gbk編碼
  • 程式碼實現
@Test
    public void test2() throws Exception {
        //1.造檔案、造流
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_gbk.txt");

        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);

        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");

        //2.讀寫過程
        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
            osw.write(cbuf,0,len);
        }

        //3.關閉資源
        isr.close();
        osw.close();
    }

八、標準輸入輸出流(瞭解)

1、簡介

  • 標準輸入流:System.in。預設輸入裝置是鍵盤。型別是InputStream。
  • 標準輸出流:System.out。預設輸出裝置是控制檯。型別是PrintStream,是OutputStream的子類。

2.練習

  • 題目:從鍵盤輸入字串,要求將讀取到的整行字串轉成大寫輸出。然後繼續 進行輸入操作,直至當輸入“e”或者“exit”時,退出程式。
  • 程式碼實現
public class Exercise {
    public static void main(String[] args) {//idea不支援在單元測試中輸入內容,所以改用main()來測試
        BufferedReader br = null;
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            br = new BufferedReader(isr);

            while (true) {
                System.out.println("請輸入字串: ");
                String data = br.readLine();
                if ("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
                    System.out.println("程式結束");
                    break;
                }
                String upperCase = data.toUpperCase();
                System.out.println(upperCase);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

九、列印流(瞭解)

1、列印流簡介

  • 實現將基本資料型別的資料格式轉化為字串輸出
  • 包含兩個:PrintStream和PrintWriter
    • 提供了一系列過載的print()和println()方法,用於多種資料型別的輸出
    • System.out返回的是PrintStream的例項

2、程式碼演示

  • 把標準輸出流(控制檯輸出)改成檔案
PrintStream ps = null; 
try {
	FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt")); // 建立列印輸出流,設定為自動重新整理模式(寫入換行符或位元組 '\n' 時都會重新整理輸出緩衝區) 
    ps = new PrintStream(fos, true); 
    if (ps != null) {// 把標準輸出流(控制檯輸出)改成檔案 
        System.setOut(ps); 
    }

	for (int i = 0; i <= 255; i++) { // 輸出ASCII字元
		System.out.print((char) i); 
        if (i % 50 == 0) { // 每50個資料一行 
            System.out.println(); // 換行 
        }
    } 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} finally {
    if (ps != null) { 
        ps.close(); 
    } 
}

十、資料流(瞭解)

1、簡介

  • 引入:為了方便地操作Java語言的基本資料型別和String的資料,可以使用資料流

  • 資料流有兩個類:(用於讀取和寫出基本資料型別、String類的資料,方便持久化)

    • DataInputStream 和 DataOutputStream

    • DataInputStream中的方法

      boolean readBoolean()

      char readChar()

      double readDouble()

      long readLong()

      String readUTF()

      byte readByte()

      float readFloat()

      short readShort()

      int readInt() void

      readFully(byte[] b)

    • DataOutputStream中的方法

      將上述的方法的read改為相應的write即可

2、練習

練習:將記憶體中的字串、基本資料型別的變數寫出到檔案中。

    注意:處理異常的話,仍然應該使用try-catch-finally.
     */
    @Test
    public void test3() throws IOException {
        //1.
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        //2.
        dos.writeUTF("劉建辰");
        dos.flush();//重新整理操作,將記憶體中的資料寫入檔案
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
        //3.
        dos.close();


    }
    /*
    將檔案中儲存的基本資料型別變數和字串讀取到記憶體中,儲存在變數中。

    注意點:讀取不同型別的資料的順序要與當初寫入檔案時,儲存的資料的順序一致!

     */
    @Test
    public void test4() throws IOException {
        //1.
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        //2.
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("isMale = " + isMale);

        //3.
        dis.close();

    }

十一、物件流

1、簡介

  • 包含:兩個類ObjectInputStream和ObjectOutputStream
  • 是:用於儲存和讀取基本資料型別資料或物件的處理流
  • 強大之處:可以把Java中的物件寫入到資料來源中,也能把物件從資料來源中還原回來。

2、物件的序列化★★★★★

  • 什麼是物件的序列化機制(面試題)

    • 一方面,物件的序列化機制允許記憶體中的Java物件轉換為平臺無關的二進位制流。從而允許吧二進位制流持久化到磁碟,或,通過網路傳給另一個網路節點
    • 另一方面,其他程式獲取了二進位制流,就可以恢復成原來的Java物件。
  • 序列化的好處:可將任何實現了Serializable接 使其在儲存和傳輸時可被還原。

3、程式碼實現String類的物件的序列化和反序列化

public class ObjectInputOutputStream {
    /*
    程式碼實現String類的物件的序列化和反序列化
     */

    @Test//序列化
    public void testObjectOutputStream(){
        ObjectOutputStream oos = null;
        try {
            //1.造流和檔案
            oos = new ObjectOutputStream(new FileOutputStream(new File("objectString.dat")));
            //2.寫出
            oos.writeObject(new String("我愛你中國"));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.關閉流
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void testObjectInputStream(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(new File("objectString.dat")));

            Object readObject = ois.readObject();
            System.out.println(readObject);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4、自定義類的序列化

  • 要求
    • 實現Serializable介面(這是一個標識介面,內部沒有方法)
    • 提供一個全域性常量public static final long serialVersionUID = xxxxxxxxL;
      • 如果類沒有顯示定義這個靜態常量,它的值是Java執行時環境根據類的內部細節自 動生成的。若類的例項變數做了修改,serialVersionUID 可能發生變化。故建議, 顯式宣告。
    • 還要保證類的所以屬性也是可序列化的。
      • 基本資料型別是可序列化的
  • 注意:ObjectOutputStream和ObjectInputStream不能序列化static和transient修飾的成員變數
    • 因為static修飾的變數是類所有的
    • 不想序列化的就可以用transient

5、面試題

  • 談談你對java.io.Serializable介面的理解,我們知道它用於序列化, 是空方法介面,還有其它認識嗎?
    • 實現了Serializable介面的物件,可將它們轉換成一系列位元組,並可在以後 完全恢復回原來的樣子。這一過程亦可通過網路進行。這意味著序列化機 制能自動補償作業系統間的差異。換句話說,可以先在Windows機器上創 建一個物件,對其序列化,然後通過網路發給一臺Unix機器,然後在那裡 準確無誤地重新“裝配”。不必關心資料在不同機器上如何表示,也不必 關心位元組的順序或者其他任何細節。
    • 由於大部分作為引數的類如String、Integer等都實現了 java.io.Serializable的介面,也可以利用多型的性質,作為引數使介面更 靈活。

十二、RandomAccessFile

1、簡介

  • RandomAccessFile,隨機存取檔案流,直接繼承於java.lang.Object類
  • 隨機:RandomAccessFile 物件包含一個記錄指標,用以標示當前讀寫處的位置。 RandomAccessFile 類物件可以自由移動記錄指標
    • long getFilePointer():獲取檔案記錄指標的當前位置
    • void seek(long pos):將檔案記錄指標定位到 pos 位置(這是他的靈魂所在)
      • 應用場景:可以多執行緒斷點下載同一檔案再拼接起來;下載不完,下次接著下載。
  • 存取:實現了DataInput、DataOutput兩個介面,所以這個類既可以讀也可以寫**。
    • 可以用構造器裡的引數決定是輸出流還是輸入流。
      • public RandomAccessFile(File file, String mode)
      • public RandomAccessFile(String name, String mode)
    • mode引數指定了訪問模式
      • r: 以只讀方式開啟 (常用)
      • rw:開啟以便讀取和寫入 (常用)
      • rwd:開啟以便讀取和寫入;同步檔案內容的更新
      • rws:開啟以便讀取和寫入;同步檔案內容和後設資料的更新

2、用RandomAccessFile類實現文字檔案的複製

@Test
public void test1() throws IOException {
    //用引數mode標識,讓類代表輸入
    RandomAccessFile r = new RandomAccessFile(new File("hello1.txt"), "r");
    //用引數mode標識,讓類代表輸出
    RandomAccessFile rw = new RandomAccessFile(new File("hello5.txt"), "rw");

    byte[] bytes = new byte[1024];
    int len;
    while ((len=r.read(bytes)) != -1){
        rw.write(bytes,0,len);
    }

    r.close();
    rw.close();
}

3、用 RandomAccessFile作為輸出流時的特點

  • 如果寫出到的檔案不存在,就建立
  • 如果寫出到的檔案存在,會對原文從頭開始進行覆蓋,能覆蓋多少算多少。

4、如何使用 RandomAccessFile對文字檔案實現插入效果

/*
    使用RandomAccessFile實現資料的插入效果
     */
    @Test
    public void test3() throws IOException {

        RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

        raf1.seek(3);//將指標調到角標為3的位置
        //儲存指標3後面的所有資料到StringBuilder中
        StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
        byte[] buffer = new byte[20];
        int len;
        while((len = raf1.read(buffer)) != -1){
            builder.append(new String(buffer,0,len)) ;
        }
        //調回指標,寫入“xyz”
        raf1.seek(3);
        raf1.write("xyz".getBytes());

        //將StringBuilder中的資料寫入到檔案中
        raf1.write(builder.toString().getBytes());

        raf1.close();
    }

十三、第三方jar包的使用

1、為什麼使用

  • 第三方jar包提供了很多方便高效的API,方便我們開發中使用,實際開發中也是用這些jar包來提高工作效率,而不只是根據JDK提供的API,因為有些不夠簡練。

2、IDEA中匯入第三方jar包

  • 當前module下建立名為lib或libs的directory
  • 複製第三方jar包到lib目錄
  • 右鍵jar包,選擇 add as library
  • 搞定

3、用第三方jar包實現檔案複製

public class JarTest {
    public static void main(String[] args) throws IOException {
        File srcFile = new File("s6_IO/hello1.txt");
        File destFile = new File("s6_IO/hello6.txt");

        FileUtils.copyFile(srcFile,destFile);

    }
}

相關文章