遞迴
這一節開頭提到了遞迴,應該是後面有用,先複習一下。
- 兩種:直接遞迴(自己呼叫自己),間接遞迴(A呼叫B,B呼叫C…)。
- 要有終止條件,否則無限呼叫導致棧記憶體溢位
- 構造方法不可遞迴
*在遍歷檔案時使用到了:只要是資料夾,就遞迴呼叫自定義遍歷方法遍歷下級資料夾
FileFilter 過濾器的原理和使用
FileFilter
- 介面,用於抽象路徑名(File 物件)的過濾器。
- 內含抽象方法
boolean accept(File pathname)
測試指定抽象路徑是否包含在某個路徑列表中- File pathName - 使用listFiles()方法遍歷目錄得到的File類物件
- 如果返回 true,則繼續遍歷;如果返回 false,則停止遍歷該 File 類物件
FilenameFilter
介面,用於過濾檔名稱
內含抽象方法
boolean accept(File dir, String name)
測試指定檔案是否包含在某一檔案列表,注意:第一個引數型別是 File 型別,第二個引數是 String 型別。
兩個介面的抽象方法都需要自己寫實現類,重寫過濾方法 accept(),自定義過濾規則。
兩個介面的區別:???
過濾器原理
- 需求: 過濾指定型別的檔案,如以.java結尾的檔案
- 明確:
- accept() 方法由誰呼叫?- listFiles()
- accept() 方法引數 pathname 是什麼?- 由 listFiles() 遍歷得到的所有 File 類檔案/檔名物件
- listFiles() 做了哪三件事?看以下程式碼:
File dir = new File("D:\\TAMU"); File[] files = dir.listFiles(new FileFilter()); // 傳遞過濾器物件給 listFiles() 方法
- listFiles() 遍歷了 dir 目錄下的每一個資料夾和檔案,並將它們封裝成 File 類物件。
- listFiles() 呼叫了 FileFilter() 中的 accept() 方法
- listFIles() 將封裝好的 File 類物件陣列傳遞給 accept 方法的引數 filename。
- listFiles() 做了哪三件事?看以下程式碼:
- 由於兩個過濾器藉口均只有一個抽象方法,我們可以在給
listFiles()
傳參時使用 Lamda 表示式實現介面,而不用額外寫一個實現類。
IO流 (輸入輸出流)
- 流:資料(字元,位元組)。1 字元 = 2位元組;1位元組 = 8 二進位制位。
- 位元組流:InputStream, OutputStream;字元流:Reader, Writer
- 為什麼要在使用完 IO 流後釋放資源?由於 Java 的垃圾回收機制無法對系統資源進行釋放,所以需要手動釋放,避免資源浪費。
位元組輸出流(OutputStream)
- OutputStream 是抽象類,把記憶體中的資料寫入磁碟的檔案中
- 資料寫入原理:java 程式 -> JVM -> OS -> OS 呼叫寫資料的方法 -> 把資料寫入檔案
- 一些共性成員方法
public void close()
關閉輸出流並釋放相關資源public void flush()
重新整理輸出流並寫出緩衝的輸出位元組public void write(byte[] b)
將b.length位元組從位元組陣列寫入輸出流public void write(byte[] b, int off, int len)
將從b[off]開始,len個位元組的資料從陣列輸出到輸出流
- 使用步驟
- 建立一個 FileOutputStream 物件,構造方法中寫入資料到目的地
- 呼叫 FileOutputStream 物件中的 write 方法,把資料寫入到檔案中
- 釋放資源
- 注意:三個步驟均需要處理 IOException; 在實際操作中構造 FileOutputStream 物件時,只有傳入絕對檔案路徑才能寫入成功,傳入相對路徑只能建立空檔案。不知道這是為什麼?
- 往檔案後追加寫資料
FileOutputStream(String name, boolean append)
或FileOutputStream(File file, boolean append)
append 為 true 時,可以在原檔案中續寫。
- 寫入換行
fos.write("\r\n".getBytes())
- 一些共性成員方法
位元組輸入流 (InputStream)
- InputStream 是抽象類,把磁碟檔案的資料讀取到記憶體中
- java 程式 -> JVM -> OS -> OS 呼叫讀取資料的方法 -> 把資料讀取出
- 一些共性成員方法
public void close()
關閉輸入流並釋放相關資源public int read()
從輸入流中讀取下一個位元組public int read(byte[] b)
從輸入流中讀取一定數量的位元組
- 使用步驟
- 建立一個 FileInputStream 物件,構造方法中傳遞資料讀取的目的地
- 呼叫 FileInputStream 物件中的 read 方法,將指定檔案中的位元組讀出
- 釋放資源
- 連續讀取檔案中位元組時會使用到迴圈,程式碼示例如下
FileInputStream fis = new FileInputStream("d:\\test\\a.txt"); int len = 0; // 用於獲取返回位元組的整型變數 while ((len = fis.read()) != -1) { // 讀取返回值為 -1 時說明檔案資料全部讀完 System.out.println((char)len); } fis.close(); // **釋放資源很重要**
- 一次讀取多個位元組的方法
int read(byte[] b)
從輸入流中讀取一定數量的位元組,並儲存在緩衝區陣列 b 中(一般定義為 1024 的倍數)- 也還是明確兩件事情:
- byte[] 陣列的作用?byte陣列,有緩衝作用。每讀取多個位元組覆蓋相應陣列空間,如果最後剩餘位元組數 n 少於陣列長度,只覆蓋前 n 個陣列空間
- 返回值 int 是什麼?是所讀取位元組的數量。如果讀完返回 -1
- 也還是明確兩件事情:
- 一些共性成員方法
本作品採用《CC 協議》,轉載必須註明作者和本文連結