java file&遞歸&字節流
1.File類
1.1File類概述和構造方法【應用】
-
File類介紹
- 它是文件和目錄路徑名的抽象表示
- 文件和目錄是可以通過File封裝成對象的
- 對于File而言,其封裝的并不是一個真正存在的文件,僅僅是一個路徑名而已。它可以是存在的,也可以是不存在的。將來是要通過具體的操作把這個路徑的內容轉換為具體存在的
-
File類的構造方法
方法名 說明 File(String pathname) 通過將給定的路徑名字符串轉換為抽象路徑名來創建新的 File實例 File(String parent, String child) 從父路徑名字符串和子路徑名字符串創建新的 File實例 File(File parent, String child) 從父抽象路徑名和子路徑名字符串創建新的 File實例 -
示例代碼
public class FileDemo01 { public static void main(String[] args) { //File(String pathname):通過將給定的路徑名字符串轉換為抽象路徑名來創建新的 File實例。 File f1 = new File("E:\\itcast\\java.txt"); System.out.println(f1); //File(String parent, String child):從父路徑名字符串和子路徑名字符串創建新的 File實例。 File f2 = new File("E:\\itcast","java.txt"); System.out.println(f2); //File(File parent, String child):從父抽象路徑名和子路徑名字符串創建新的 File實例。 File f3 = new File("E:\\itcast"); File f4 = new File(f3,"java.txt"); System.out.println(f4); } }
1.2File類創建功能【應用】
-
方法分類
方法名 說明 public boolean createNewFile() 當具有該名稱的文件不存在時,創建一個由該抽象路徑名命名的新空文件 public boolean mkdir() 創建由此抽象路徑名命名的目錄 public boolean mkdirs() 創建由此抽象路徑名命名的目錄,包括任何必需但不存在的父目錄 -
示例代碼
public class FileDemo02 { public static void main(String[] args) throws IOException { //需求1:我要在E:\\itcast目錄下創建一個文件java.txt File f1 = new File("E:\\itcast\\java.txt"); System.out.println(f1.createNewFile()); System.out.println("--------"); //需求2:我要在E:\\itcast目錄下創建一個目錄JavaSE File f2 = new File("E:\\itcast\\JavaSE"); System.out.println(f2.mkdir()); System.out.println("--------"); //需求3:我要在E:\\itcast目錄下創建一個多級目錄JavaWEB\\HTML File f3 = new File("E:\\itcast\\JavaWEB\\HTML"); // System.out.println(f3.mkdir()); System.out.println(f3.mkdirs()); System.out.println("--------"); //需求4:我要在E:\\itcast目錄下創建一個文件javase.txt File f4 = new File("E:\\itcast\\javase.txt"); // System.out.println(f4.mkdir()); System.out.println(f4.createNewFile()); } }
1.3File類判斷和獲取功能【應用】
-
判斷功能
方法名 說明 public boolean isDirectory() 測試此抽象路徑名表示的File是否為目錄 public boolean isFile() 測試此抽象路徑名表示的File是否為文件 public boolean exists() 測試此抽象路徑名表示的File是否存在 -
獲取功能
方法名 說明 public String getAbsolutePath() 返回此抽象路徑名的絕對路徑名字符串 public String getPath() 將此抽象路徑名轉換為路徑名字符串 public String getName() 返回由此抽象路徑名表示的文件或目錄的名稱 public String[] list() 返回此抽象路徑名表示的目錄中的文件和目錄的名稱字符串數組 public File[] listFiles() 返回此抽象路徑名表示的目錄中的文件和目錄的File對象數組 -
示例代碼
public class FileDemo04 { public static void main(String[] args) { //創建一個File對象 File f = new File("myFile\\java.txt"); // public boolean isDirectory():測試此抽象路徑名表示的File是否為目錄 // public boolean isFile():測試此抽象路徑名表示的File是否為文件 // public boolean exists():測試此抽象路徑名表示的File是否存在 System.out.println(f.isDirectory()); System.out.println(f.isFile()); System.out.println(f.exists()); // public String getAbsolutePath():返回此抽象路徑名的絕對路徑名字符串 // public String getPath():將此抽象路徑名轉換為路徑名字符串 // public String getName():返回由此抽象路徑名表示的文件或目錄的名稱 System.out.println(f.getAbsolutePath()); System.out.println(f.getPath()); System.out.println(f.getName()); System.out.println("--------"); // public String[] list():返回此抽象路徑名表示的目錄中的文件和目錄的名稱字符串數組 // public File[] listFiles():返回此抽象路徑名表示的目錄中的文件和目錄的File對象數組 File f2 = new File("E:\\itcast"); String[] strArray = f2.list(); for(String str : strArray) { System.out.println(str); } System.out.println("--------"); File[] fileArray = f2.listFiles(); for(File file : fileArray) { // System.out.println(file); // System.out.println(file.getName()); if(file.isFile()) { System.out.println(file.getName()); } } } }
1.4File類刪除功能【應用】
-
方法分類
方法名 說明 public boolean delete() 刪除由此抽象路徑名表示的文件或目錄 -
示例代碼
public class FileDemo03 { public static void main(String[] args) throws IOException { // File f1 = new File("E:\\itcast\\java.txt"); //需求1:在當前模塊目錄下創建java.txt文件 File f1 = new File("myFile\\java.txt"); // System.out.println(f1.createNewFile()); //需求2:刪除當前模塊目錄下的java.txt文件 System.out.println(f1.delete()); System.out.println("--------"); //需求3:在當前模塊目錄下創建itcast目錄 File f2 = new File("myFile\\itcast"); // System.out.println(f2.mkdir()); //需求4:刪除當前模塊目錄下的itcast目錄 System.out.println(f2.delete()); System.out.println("--------"); //需求5:在當前模塊下創建一個目錄itcast,然后在該目錄下創建一個文件java.txt File f3 = new File("myFile\\itcast"); // System.out.println(f3.mkdir()); File f4 = new File("myFile\\itcast\\java.txt"); // System.out.println(f4.createNewFile()); //需求6:刪除當前模塊下的目錄itcast System.out.println(f4.delete()); System.out.println(f3.delete()); } } -
絕對路徑和相對路徑的區別
- 絕對路徑:完整的路徑名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\itcast\java.txt
- 相對路徑:必須使用取自其他路徑名的信息進行解釋。例如:myFile\java.txt
2.遞歸
2.1遞歸【應用】
-
遞歸的介紹
- 以編程的角度來看,遞歸指的是方法定義中調用方法本身的現象
- 把一個復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解
- 遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算
-
遞歸的基本使用
public class DiGuiDemo { public static void main(String[] args) { //回顧不死神兔問題,求第20個月兔子的對數 //每個月的兔子對數:1,1,2,3,5,8,... int[] arr = new int[20]; arr[0] = 1; arr[1] = 1; for (int i = 2; i < arr.length; i++) { arr[i] = arr[i - 1] + arr[i - 2]; } System.out.println(arr[19]); System.out.println(f(20)); } /* 遞歸解決問題,首先就是要定義一個方法: 定義一個方法f(n):表示第n個月的兔子對數 那么,第n-1個月的兔子對數該如何表示呢?f(n-1) 同理,第n-2個月的兔子對數該如何表示呢?f(n-2) StackOverflowError:當堆棧溢出發生時拋出一個應用程序遞歸太深 */ public static int f(int n) { if(n==1 || n==2) { return 1; } else { return f(n - 1) + f(n - 2); } } } -
遞歸的注意事項
- 遞歸一定要有出口。否則內存溢出
- 遞歸雖然有出口,但是遞歸的次數也不宜過多。否則內存溢出
2.2遞歸求階乘【應用】
-
案例需求
? 用遞歸求5的階乘,并把結果在控制臺輸出
-
代碼實現
public class DiGuiDemo01 { public static void main(String[] args) { //調用方法 int result = jc(5); //輸出結果 System.out.println("5的階乘是:" + result); } //定義一個方法,用于遞歸求階乘,參數為一個int類型的變量 public static int jc(int n) { //在方法內部判斷該變量的值是否是1 if(n == 1) { //是:返回1 return 1; } else { //不是:返回n*(n-1)! return n*jc(n-1); } } }
2.3遞歸遍歷目錄【應用】
-
案例需求
? 給定一個路徑(E:\itcast),通過遞歸完成遍歷該目錄下所有內容,并把所有文件的絕對路徑輸出在控制臺
-
代碼實現
public class DiGuiDemo02 { public static void main(String[] args) { //根據給定的路徑創建一個File對象 // File srcFile = new File("E:\\itcast"); File srcFile = new File("E:\\itheima"); //調用方法 getAllFilePath(srcFile); } //定義一個方法,用于獲取給定目錄下的所有內容,參數為第1步創建的File對象 public static void getAllFilePath(File srcFile) { //獲取給定的File目錄下所有的文件或者目錄的File數組 File[] fileArray = srcFile.listFiles(); //遍歷該File數組,得到每一個File對象 if(fileArray != null) { for(File file : fileArray) { //判斷該File對象是否是目錄 if(file.isDirectory()) { //是:遞歸調用 getAllFilePath(file); } else { //不是:獲取絕對路徑輸出在控制臺 System.out.println(file.getAbsolutePath()); } } } } }
3.IO流
3.1 IO流概述和分類【理解】
- IO流介紹
- IO:輸入/輸出(Input/Output)
- 流:是一種抽象概念,是對數據傳輸的總稱。也就是說數據在設備間的傳輸稱為流,流的本質是數據傳輸
- IO流就是用來處理設備間數據傳輸問題的。常見的應用:文件復制;文件上傳;文件下載
- IO流的分類
- 按照數據的流向
- 輸入流:讀數據
- 輸出流:寫數據
- 按照數據類型來分
- 字節流
- 字節輸入流
- 字節輸出流
- 字符流
- 字符輸入流
- 字符輸出流
- 字節流
- 按照數據的流向
- IO流的使用場景
- 如果操作的是純文本文件,優先使用字符流
- 如果操作的是圖片、視頻、音頻等二進制文件。優先使用字節流
- 如果不確定文件類型,優先使用字節流。字節流是萬能的流
3.2字節流寫數據【應用】
-
字節流抽象基類
- InputStream:這個抽象類是表示字節輸入流的所有類的超類
- OutputStream:這個抽象類是表示字節輸出流的所有類的超類
- 子類名特點:子類名稱都是以其父類名作為子類名的后綴
-
字節輸出流
- FileOutputStream(String name):創建文件輸出流以指定的名稱寫入文件
-
使用字節輸出流寫數據的步驟
- 創建字節輸出流對象(調用系統功能創建了文件,創建字節輸出流對象,讓字節輸出流對象指向文件)
- 調用字節輸出流對象的寫數據方法
- 釋放資源(關閉此文件輸出流并釋放與此流相關聯的任何系統資源)
-
示例代碼
public class FileOutputStreamDemo01 { public static void main(String[] args) throws IOException { //創建字節輸出流對象 //FileOutputStream(String name):創建文件輸出流以指定的名稱寫入文件 FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt"); /* 做了三件事情: A:調用系統功能創建了文件 B:創建了字節輸出流對象 C:讓字節輸出流對象指向創建好的文件 */ //void write(int b):將指定的字節寫入此文件輸出流 fos.write(97); // fos.write(57); // fos.write(55); //最后都要釋放資源 //void close():關閉此文件輸出流并釋放與此流相關聯的任何系統資源。 fos.close(); } }
3.3字節流寫數據的三種方式【應用】
-
寫數據的方法分類
方法名 說明 void write(int b) 將指定的字節寫入此文件輸出流 一次寫一個字節數據 void write(byte[] b) 將 b.length字節從指定的字節數組寫入此文件輸出流 一次寫一個字節數組數據 void write(byte[] b, int off, int len) 將 len字節從指定的字節數組開始,從偏移量off開始寫入此文件輸出流 一次寫一個字節數組的部分數據 -
示例代碼
public class FileOutputStreamDemo02 { public static void main(String[] args) throws IOException { //FileOutputStream(String name):創建文件輸出流以指定的名稱寫入文件 FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt"); //new File(name) // FileOutputStream fos = new FileOutputStream(new File("myByteStream\\fos.txt")); //FileOutputStream(File file):創建文件輸出流以寫入由指定的 File對象表示的文件 // File file = new File("myByteStream\\fos.txt"); // FileOutputStream fos2 = new FileOutputStream(file); // FileOutputStream fos2 = new FileOutputStream(new File("myByteStream\\fos.txt")); //void write(int b):將指定的字節寫入此文件輸出流 // fos.write(97); // fos.write(98); // fos.write(99); // fos.write(100); // fos.write(101); // void write(byte[] b):將 b.length字節從指定的字節數組寫入此文件輸出流 // byte[] bys = {97, 98, 99, 100, 101}; //byte[] getBytes():返回字符串對應的字節數組 byte[] bys = "abcde".getBytes(); // fos.write(bys); //void write(byte[] b, int off, int len):將 len字節從指定的字節數組開始,從偏移量off開始寫入此文件輸出流 // fos.write(bys,0,bys.length); fos.write(bys,1,3); //釋放資源 fos.close(); } }
3.4字節流寫數據的兩個小問題【應用】
-
字節流寫數據如何實現換行
- windows:\r\n
- linux:\n
- mac:\r
-
字節流寫數據如何實現追加寫入
- public FileOutputStream(String name,boolean append)
- 創建文件輸出流以指定的名稱寫入文件。如果第二個參數為true ,則字節將寫入文件的末尾而不是開頭
-
示例代碼
public class FileOutputStreamDemo03 { public static void main(String[] args) throws IOException { //創建字節輸出流對象 // FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt"); FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt",true); //寫數據 for (int i = 0; i < 10; i++) { fos.write("hello".getBytes()); fos.write("\r\n".getBytes()); } //釋放資源 fos.close(); } }
3.5字節流寫數據加異常處理【應用】
-
異常處理格式
-
try-catch-finally
try{ 可能出現異常的代碼; }catch(異常類名 變量名){ 異常的處理代碼; }finally{ 執行所有清除操作; } -
finally特點
- 被finally控制的語句一定會執行,除非JVM退出
-
-
示例代碼
public class FileOutputStreamDemo04 { public static void main(String[] args) { //加入finally來實現釋放資源 FileOutputStream fos = null; try { fos = new FileOutputStream("myByteStream\\fos.txt"); fos.write("hello".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { if(fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.6字節流讀數據(一次讀一個字節數據)【應用】
-
字節輸入流
- FileInputStream(String name):通過打開與實際文件的連接來創建一個FileInputStream ,該文件由文件系統中的路徑名name命名
-
字節輸入流讀取數據的步驟
- 創建字節輸入流對象
- 調用字節輸入流對象的讀數據方法
- 釋放資源
-
示例代碼
public class FileInputStreamDemo01 { public static void main(String[] args) throws IOException { //創建字節輸入流對象 //FileInputStream(String name) FileInputStream fis = new FileInputStream("myByteStream\\fos.txt"); int by; /* fis.read():讀數據 by=fis.read():把讀取到的數據賦值給by by != -1:判斷讀取到的數據是否是-1 */ while ((by=fis.read())!=-1) { System.out.print((char)by); } //釋放資源 fis.close(); } }
3.7字節流復制文本文件【應用】
-
案例需求
? 把“E:\itcast\窗里窗外.txt”復制到模塊目錄下的“窗里窗外.txt”
-
實現步驟
-
復制文本文件,其實就把文本文件的內容從一個文件中讀取出來(數據源),然后寫入到另一個文件中(目的地)
-
數據源:
? E:\itcast\窗里窗外.txt --- 讀數據 --- InputStream --- FileInputStream
-
目的地:
? myByteStream\窗里窗外.txt --- 寫數據 --- OutputStream --- FileOutputStream
-
-
代碼實現
public class CopyTxtDemo { public static void main(String[] args) throws IOException { //根據數據源創建字節輸入流對象 FileInputStream fis = new FileInputStream("E:\\itcast\\窗里窗外.txt"); //根據目的地創建字節輸出流對象 FileOutputStream fos = new FileOutputStream("myByteStream\\窗里窗外.txt"); //讀寫數據,復制文本文件(一次讀取一個字節,一次寫入一個字節) int by; while ((by=fis.read())!=-1) { fos.write(by); } //釋放資源 fos.close(); fis.close(); } }
3.8字節流讀數據(一次讀一個字節數組數據)【應用】
-
一次讀一個字節數組的方法
- public int read(byte[] b):從輸入流讀取最多b.length個字節的數據
- 返回的是讀入緩沖區的總字節數,也就是實際的讀取字節個數
-
示例代碼
public class FileInputStreamDemo02 { public static void main(String[] args) throws IOException { //創建字節輸入流對象 FileInputStream fis = new FileInputStream("myByteStream\\fos.txt"); /* hello\r\n world\r\n 第一次:hello 第二次:\r\nwor 第三次:ld\r\nr */ byte[] bys = new byte[1024]; //1024及其整數倍 int len; while ((len=fis.read(bys))!=-1) { System.out.print(new String(bys,0,len)); } //釋放資源 fis.close(); } }
3.9字節流復制圖片【應用】
-
案例需求
? 把“E:\itcast\mn.jpg”復制到模塊目錄下的“mn.jpg”
-
實現步驟
- 根據數據源創建字節輸入流對象
- 根據目的地創建字節輸出流對象
- 讀寫數據,復制圖片(一次讀取一個字節數組,一次寫入一個字節數組)
- 釋放資源
-
代碼實現
public class CopyJpgDemo { public static void main(String[] args) throws IOException { //根據數據源創建字節輸入流對象 FileInputStream fis = new FileInputStream("E:\\itcast\\mn.jpg"); //根據目的地創建字節輸出流對象 FileOutputStream fos = new FileOutputStream("myByteStream\\mn.jpg"); //讀寫數據,復制圖片(一次讀取一個字節數組,一次寫入一個字節數組) byte[] bys = new byte[1024]; int len; while ((len=fis.read(bys))!=-1) { fos.write(bys,0,len); } //釋放資源 fos.close(); fis.close(); } }
浙公網安備 33010602011771號