01異常的概述
* A: 異常的概述
* a:什麼是異常
* Java代碼在運行時期發生的問題就是異常。
* b:異常類
* 在Java中,把異常信息封裝成了一個類。
* 當出現了問題時,就會創建異常類對象並拋出異常相關的信息(如異常出現的位置、原因等)。
* c:我們見過的異常:數組角標越界異常ArrayIndexOutOfBoundsException,空指針異常NullPointerException
02異常的繼續體系和錯誤的區別
* A: 異常的繼承體系
Throwable: 它是所有錯誤與異常的超類(祖宗類)
|- Error 錯誤
|- Exception 編譯期異常,進行編譯JAVA程序時出現的問題
|- RuntimeException 運行期異常, JAVA程序運行過程中出現的問題
* B:異常與錯誤的區別
* a:異常
* 指程序在編譯、運行期間發生了某種異常(XxxException),我們可以對異常進行具體的處理。
* 若不處理異常,程序將會結束運行。
* 案例演示:
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[0]);
System.out.println(arr[3]);
// 該句運行時發生了數組索引越界異常ArrayIndexOutOfBoundsException,
// 由於沒有處理異常,導致程序無法繼續執行,程序結束。
System.out.println("over"); // 由於上面代碼發生了異常,此句代碼不會執行
}
* b:錯誤
* 指程序在運行期間發生了某種錯誤(XxxError),Error錯誤通常沒有具體的處理方式,程序將會結束運行。
* Error錯誤的發生往往都是系統級別的問題,都是jvm所在系統發生的,並反饋給jvm的。
* 我們無法針對處理,只能修正代碼。
* 案例演示:
public static void main(String[] args) {
int[] arr = new int[1024*1024*100];
//該句運行時發生了內存溢出錯誤OutOfMemoryError,開闢了過大的數組空間,
//導致JVM在分配數組空間時超出了JVM內存空間,直接發生錯誤。
}
03異常對象的產生原因和處理方式
* A: 異常對象的產生原因
* 案例代碼:
* 工具類
class ArrayTools{
//對給定的數組通過給定的角標獲取元素。
public static int getElement(int[] arr,int index) {
int element = arr[index];
return element;
}
}
* 測試類
class ExceptionDemo2 {
public static void main(String[] args) {
int[] arr = {34,12,67};
int num = ArrayTools.getElement(arr,4)
System.out.println("num="+num);
System.out.println("over");
}
}
* 原因分析:
* a: 由於沒找到4索引,導致運行時發生了異常。這個異常JVM認識:ArrayIndexOutOfBoundsException。
這個異常Java本身有描述:異常的名稱、異常的內容、異常的產生位置。
java將這些信息直接封裝到異常對象中。new ArrayIndexOutOfBoundsException(4);
* b:throw new ArrayIndexOutOfBoundsException(4);產生異常對象。JVM將產生的異常拋給調用者main()方法。
* c:main()方法接收到了數組索引越界異常對象。
由於main()方法並沒有進行處理異常,main()方法就會繼續把異常拋給調用者JVM。
當JVM收到異常後,將異常對象中的名稱、異常內容、位置都顯示在就控制檯上。同時讓程序立刻終止。
* B:異常的處理方式
* a:JVM的默認處理方式
* 把異常的名稱,原因,位置等信息輸出在控制檯,同時會結束程序。
* 一旦有異常發生,其後來的代碼不能繼續執行。
* b:解決程序中異常的手動方式
* a):編寫處理代碼 try...catch...finally
* b):拋出 throws
04方法內部拋出對象throw關鍵字
在java中,提供了一個throw關鍵字,它用來拋出一個指定的異常對象。
* A: 什麼時候使用throw關鍵字?
* 當調用方法使用接受到的參數時,首先需要先對參數數據進行合法的判斷,
數據若不合法,就應該告訴調用者,傳遞合法的數據進來。
這時需要使用拋出異常的方式來告訴調用者。
* B: 使用throw關鍵字具體操作
* a: 創建一個異常對象。封裝一些提示信息(信息可以自己編寫)。
* b: 通過關鍵字throw將這個異常對象告知給調用者。throw 異常對象;
throw 用在方法內,用來拋出一個異常對象,將這個異常對象傳遞到調用者處,並結束當前方法的執行。
* C: throw關鍵字使用格式
* throw new 異常類名(參數);
* 例如:
throw new NullPointerException("要訪問的arr數組不存在");
throw new ArrayIndexOutOfBoundsException("該索引在數組中不存在,已超出範圍");
* D:案例演示
* throw的使用
05方法聲明異常關鍵字throws
* A: 聲明
* 將問題標識出來,報告給調用者。如果方法內通過throw拋出了編譯時異常,而沒有捕獲處理(稍後講解該方式),那麼必須通過throws進行聲明,讓調用者去處理。
* B: 聲明異常格式
* 修飾符 返回值類型 方法名(參數) throws 異常類名1,異常類名2… { }
* C:注意事項:
* throws用於進行異常類的聲明,若該方法可能有多種異常情況產生,那麼在throws後面可以寫多個異常類,用逗號隔開。
* D:代碼演示:
* 多個異常的處理
==============================第二節課開始====================================
06try…catch異常處理
* A: 捕獲
* Java中對異常有針對性的語句進行捕獲,可以對出現的異常進行指定方式的處理
* B: 捕獲異常格式
try {
//需要被檢測的語句。
}
catch(異常類 變量) { //參數。
//異常的處理語句。
}
finally {
//一定會被執行的語句。
}
* C: 格式說明
* a: try
* 該代碼塊中編寫可能產生異常的代碼。
* b: catch
* 用來進行某種異常的捕獲,實現對捕獲到的異常進行處理。
* c: finally:
* 有一些特定的代碼無論異常是否發生,都需要執行。
* 另外,因爲異常會引發程序跳轉,導致有些語句執行不到。
* 而finally就是解決這個問題的,在finally代碼塊中存放的代碼都是一定會被執行的。
* d:try...catch...處理掉異常後,程序可以繼續執行
* D:案例演示
* 捕獲異常格式
07多catch處理
* A:一個try 多個catch組合
* 對代碼進行異常檢測,並對檢測的異常傳遞給catch處理。對每種異常信息進行不同的捕獲處理。
* B:多catch處理的格式
void show(){ //不用throws
try{
throw new Exception();//產生異常,直接捕獲處理
}catch(XxxException e){
//處理方式
}catch(YyyException e){
//處理方式
}catch(ZzzException e){
//處理方式
}
}
注意事項:在捕獲異常處理中,變量也是有作用域的,如可以定義多個catch中異常變量名爲e。
08多catch處理細節
* A:細節:多個catch小括號中,寫的是異常類的類名,有沒有順序的概念?
* 有順序關係。
* B:平級異常:
* 拋出的異常類之間,沒有繼承關係,沒有順序
NullPointerException extends RuntimeException
NoSuchElementException extends RuntimeException
ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException extends RuntimeException
* C:上下級關係的異常
* 越高級的父類,越寫在下面
NullPointerException extends RuntimeException extends Exception
09finally代碼塊
* A: finally的特點
* 被finally控制的語句體一定會執行
* B:finally的作用
* finally,無論程序是否有異常出現,程序必須執行釋放資源在
如:IO流操作和數據庫操作中會見到
10調用拋出異常方法try和throws處理方式
* A: 在實際開發中使用哪種異常處理方式呢?
* 能自己處理的儘量自己處理。(建議用try...catch)
==============================第三節課開始====================================
11運行時期異常的特點
* A: 運行時期異常的概述:
* RuntimeException和他的所有子類異常,都屬於運行時期異常。
NullPointerException,ArrayIndexOutOfBoundsException等都屬於運行時期異常.
* B:運行時期異常的特點
* a:方法中拋出運行時期異常,方法定義中無需throws聲明,調用者也無需處理此異常。
* b:運行時期異常一旦發生,需要程序人員修改源代碼。
設計原因:
運行異常,不能發生,但是如果發生了,程序人員停止程序修改源代碼
運行異常: 一旦發生,不要處理,請你修改源代碼,運行異常一旦發生,後面的代碼沒有執行的意義
12運行異常的案例
* A: 計算圓的面積案例
定義方法,計算圓形的面積
傳遞參數0,或者負數,計算的時候沒有問題
但是,違反了真實情況
參數小於=0, 停止程序,不要在計算了
* B:數組索引越界案例
使用數組中不存在的索引
public class RuntimeExceptionDemo {
public static void main(String[] args) {
double d = getArea(1);
System.out.println(d);
}
/*
* 定義方法,計算圓形的面積
* 傳遞參數0,或者負數,計算的時候沒有問題
* 但是,違反了真實情況
* 參數小於=0, 停止程序,不要在計算了
*/
public static double getArea(double r){
if(r <= 0)
throw new RuntimeException("圓形不存在");
return r*r*Math.PI;
}
public static void function(){
int[] arr = {1,2,3};
//對數組的5索引進行判斷,如果5索引大於100,請將5索引上的數據/2,否則除以3
//索引根本就沒有
if(arr[5] > 100){
arr[5] = arr[5]/2;
}else{
arr[5] = arr[5]/3;
}
}
13方法重寫時候異常的處理
* A:方法重寫時候異常的處理
* a:子類覆蓋父類方法時,如果父類的方法聲明異常,子類只能聲明父類異常或者該異常的子類,或者不聲明。
例如:
class Fu {
public void method () throws RuntimeException {
}
}
class Zi extends Fu {
public void method() throws RuntimeException { } //拋出父類一樣的異常
//public void method() throws NullPointerException{ } //拋出父類子異常
}
* b:當父類方法聲明多個異常時,子類覆蓋時只能聲明多個異常的子集。
例如:
class Fu {
public void method () throws NullPointerException, ClassCastException{
}
}
class Zi extends Fu {
public void method()throws NullPointerException, ClassCastException { }
public void method() throws NullPointerException{ } //拋出父類異常中的一部分
public void method() throws ClassCastException { } //拋出父類異常中的一部分
}
* c:當被覆蓋的方法沒有異常聲明時,子類覆蓋時無法聲明異常的。
例如:
class Fu {
public void method (){
}
}
class Zi extends Fu {
public void method() throws Exception { }//錯誤的方式
}
* B:問題:父類中會存在下列這種情況,接口也有這種情況。
接口中沒有聲明異常,而實現的子類覆蓋方法時發生了異常,怎麼辦?
回答:無法進行throws聲明,只能catch的捕獲。
萬一問題處理不了呢?catch中繼續throw拋出,但是隻能將異常轉換成RuntimeException子類拋出。
14Throwable類方法
* A: 常見方法
* a:getMessage()方法
返回該異常的詳細信息字符串,即異常提示信息
* b:toString()方法
返回該異常的名稱與詳細信息字符串
* c:printStackTrace()方法
在控制檯輸出該異常的名稱與詳細信息字符串、異常出現的代碼位置
* B:案例演示
異常的常用方法代碼演示
try {
Person p= null;
if (p==null) {
throw new NullPointerException(“出現空指針異常了,請檢查對象是否爲null”);
}
} catch (NullPointerException e) {
String message = e.getMesage();
System.out.println(message );
String result = e.toString();
System.out.println(result);
e.printStackTrace();
}
======================第四節課開始=========
15自定義異常
* A: 自定義異常的定義
* a:通過閱讀源碼,發現規律:
每個異常中都調用了父類的構造方法,把異常描述信息傳遞給了父類,讓父類幫我們進行異常信息的封裝。
* b:格式:
Class 異常名 extends Exception{ //或繼承RuntimeException
public 異常名(){
}
public 異常名(String s){
super(s);
}
}
* c:自定義異常繼承Exception演示
* d:自定義異常繼承RuntimeException演示
* B:自定義異常的練習
在Person類的有參數構造方法中,進行年齡範圍的判斷,
若年齡爲負數或大於200歲,則拋出NoAgeException異常,異常提示信息“年齡數值非法”。
要求:在測試類中,調用有參數構造方法,完成Person對象創建,並進行異常的處理。
* C:關於構造方法拋出異常總結
構造函數到底拋出這個NoAgeException是繼承Exception呢?還是繼承RuntimeException呢?
* a:繼承Exception,必須要throws聲明,一聲明就告知調用者進行捕獲,一旦問題處理了調用者的程序會繼續執行。
* b:繼承RuntimeExcpetion,不需要throws聲明的,這時調用是不需要編寫捕獲代碼的,因爲調用根本就不知道有問題。
一旦發生NoAgeException,調用者程序會停掉,並有jvm將信息顯示到屏幕,讓調用者看到問題,修正代碼。
01IO技術概述.avi(02:49)
* A:IO技術概述
* a: Output
* 把內存中的數據存儲到持久化設備上這個動作稱爲輸出(寫)Output操作
* b: Input
* 把持久設備上的數據讀取到內存中的這個動作稱爲輸入(讀)Input操作
* c: IO操作
* 把上面的這種輸入和輸出動作稱爲IO操作
02File類的概述和作用
* A:File類的概述和作用
* a: File的概念
* File類是文件和目錄路徑名的抽象表示形式
* Java中把文件或者目錄(文件夾)都封裝成File對象
* 我們要去操作硬盤上的文件,或者文件夾只要找到File這個類即可
03File類靜態的成員變量
* A:File類靜態的成員變量
* a: pathSeparator
* 與系統有關的路徑分隔符,爲了方便,它被表示爲一個字符串
* b: separator
* 與系統有關的默認名稱分隔符,爲了方便,它被表示爲一個字符串
* c: 案例代碼
/*
* java.io.File
* 將操作系統中的,文件,目錄(文件夾),路徑,封裝成File對象
* 提供方法,操作系統中的內容
* File與系統無關的類
* 文件 file
* 目錄 directory
* 路徑 path
*/
public class FileDemo {
public static void main(String[] args) {
//File類靜態成員變量
//與系統有關的路徑分隔符
String separator = File.pathSeparator;
System.out.println(separator);// 是一個分號,目錄的分割(window中環境變量配置各個路徑用分號分割,表示一個完整的路徑結束) Linux中是冒號 :
//與系統有關的默認名稱分隔符
separator = File.separator;
System.out.println(separator);// 向右 \ 目錄名稱分割 Linux /
}
}
04File類構造方法_1
* A: File類構造方法_1
* a: File(String pathname)
* 通過將給定路徑名字符串轉換爲一個File對象,之後可以使用File中的方法
* windows中的路徑或文件名不區分大小寫
* d: 案例代碼
public class FileDemo1 {
public static void main(String[] args) {
function();
}
/*
* File(String pathname)
* 傳遞路徑名: 可以寫到文件夾,可以寫到一個文件
* c:\\abc c:\\abc\\Demo.java
* 將路徑封裝File類型對象
*/
public static void function(){
File file = new File("d:\\eclipse");
System.out.println(file);
}
}
05相對路徑和絕對路徑
* A: 相對路徑和絕對路徑
* a: 絕對路徑
* 絕對路徑是一個固定的路徑,從盤符開始
* b: 相對路徑
* 相對路徑相對於某個位置,在eclipse下是指當前項目下
* c: 路徑
絕對路徑
在系統中具有唯一性
c:\\windows\\system32
相對路徑
表示路徑之間的關係
D:\\develop\\Java\\jdk1.7.0_72\\bin
D:\\develop\\Java\\jre7
路徑之間關係
Java 父目錄是D:\\develop
Java 子目錄是:jdk1.7.0_72
父路徑是 唯一性
子目錄是可以多個
06File類的構造方法_2
* A: File類的構造方法_2
* a:File(String parent, String child)
* 根據 parent 路徑名字符串和 child 路徑名字符串創建一個新 File 對象
* b: File(File parent, String child)
* c: 案例代碼
public class FileDemo1 {
public static void main(String[] args) {
function_2();
}
/*
* File(File parent,String child)
* 傳遞路徑,傳遞File類型父路徑,字符串子路徑
* 好處: 父路徑是File類型,父路徑可以直接調用File類方法
*/
public static void function_2(){
File parent = new File("d:");
File file = new File(parent,"eclipse");
System.out.println(file);
}
/*
* File(String parent,String child)
* 傳遞路徑,傳遞字符串父路徑,字符串子路徑
* 好處: 單獨操作父路徑和子路徑
*/
public static void function_1(){
File file = new File("d:","eclipse");
System.out.println(file);
}
}
07File類創建文件功能
* A: File類創建文件功能
* a: public boolean createNewFile()
* 創建文件 如果存在這樣的文件,就不創建了
* b: 案例代碼
public class FileDemo2 {
public static void main(String[] args)throws IOException {
function();
}
/*
* File創建文件的功能
* boolean createNewFile()
* 創建的文件路徑和文件名,在File構造方法中給出
* 文件已經存在了,不在創建
*/
public static void function()throws IOException{
File file = new File("c:\\a.txt");
boolean b = file.createNewFile();
System.out.println(b);
}
}
08File類創建目錄功能
* A: File類創建目錄功能
* a: 創建目錄
* public boolean mkdir():創建文件夾 如果存在這樣的文件夾,就不創建了
* public boolean mkdirs():創建文件夾,如果父文件夾不存在,會幫你創建出來
* b: 案例代碼
public class FileDemo2 {
public static void main(String[] args)throws IOException {
function_1();
}
/*
* File創建文件夾功能
* boolean mkdirs() 創建多層文件夾
* 創建的路徑也在File構造方法中給出
* 文件夾已經存在了,不在創建
*/
public static void function_1(){
File file = new File("c:\\abc");
boolean b = file.mkdirs();
System.out.println(b);
}
}
###09File類刪除功能
* A: File類刪除功能
* a: 刪除功能
* public boolean delete():刪除文件或者文件夾
* B: 案例代碼
public class FileDemo2 {
public static void main(String[] args)throws IOException {
function_2();
}
/*
* File類的刪除功能
* boolean delete()
* 刪除的文件或者是文件夾,在File構造方法中給出
* 刪除成功返回true,刪除失敗返回false
* 刪除方法,不走回收站,直接從硬盤中刪除
* 刪除有風險,運行需謹慎
*/
public static void function_2(){
File file = new File("c:\\a.txt");
boolean b = file.delete();
System.out.println(b);
}
}
10File類獲取功能
* A:File類獲取功能
* a: 方法介紹
* String getName(): 返回路徑中表示的文件或者文件夾名
* 獲取路徑中的最後部分的名字
* long length(): 返回路徑中表示的文件的字節數
* String getAbsolutePath(): 獲取絕對路徑,返回String對象
* File getAbsoluteFile() : 獲取絕對路徑,返回File對象
* eclipse環境中,寫一個相對路徑,絕對位置工程根目錄
* String getParent(): 獲取父路徑,返回String對象
* File getParentFile(): 獲取父路徑,返回File對象
* b: 案例代碼
public class FileDemo3 {
public static void main(String[] args) {
function_3();
}
/*
* File類的獲取功能
* String getParent() 返回String對象
* File getParentFile()返回File對象
* 獲取父路徑
*/
public static void function_3(){
File file = new File("d:\\eclipse\\eclipse.exe");
File parent = file.getParentFile();
System.out.println(parent);
}
/*
* File類獲取功能
* String getAbsolutePath() 返回String對象
* File getAbsoluteFile() 返回File對象
* 獲取絕對路徑
* eclipse環境中,寫的是一個相對路徑,絕對位置工程根目錄
*/
public static void function_2(){
File file = new File("src");
File absolute = file.getAbsoluteFile();
System.out.println(absolute);
}
/*
* File類獲取功能
* long length()
* 返回路徑中表示的文件的字節數
*/
public static void function_1(){
File file = new File("d:\\eclipse\\eclipse.exe");
long length = file.length();
System.out.println(length);
}
/*
* File類的獲取功能
* String getName()
* 返回路徑中表示的文件或者文件夾名
* 獲取路徑中的最後部分的名字
*/
public static void function(){
File file = new File("d:\\eclipse\\eclipse.exe");
String name = file.getName();
System.out.println(name);
/*String path = file.getPath();
System.out.println(path);*/
// System.out.println(file);
}
}
11File類判斷功能
* A: File類判斷功能
* a: 方法介紹
* boolean exists(): 判斷File構造方法中封裝路徑是否存在
* 存在返回true,不存在返回false
* boolean isDirectory(): 判斷File構造方法中封裝的路徑是不是文件夾
* 如果是文件夾,返回true,不是文件返回false
* boolean isFile(): 判斷File構造方法中封裝的路徑是不是文件
* 如果是文件,返回true,不是文件返回false
* b: 案例代碼
public class FileDemo4 {
public static void main(String[] args) {
function_1();
}
/*
* File判斷功能
* boolean isDirectory()
* 判斷File構造方法中封裝的路徑是不是文件夾
* 如果是文件夾,返回true,不是文件返回false
*
* boolean isFile()
* 判斷File構造方法中封裝的路徑是不是文件
*/
public static void function_1(){
File file = new File("d:\\eclipse\\eclipse.exe");
if(file.exists()){
boolean b = file.isDirectory();
System.out.println(b);
}
}
/*
* File判斷功能
* boolean exists()
* 判斷File構造方法中封裝路徑是否存在
* 存在返回true,不存在返回false
*/
public static void function(){
File file = new File("src");
boolean b = file.exists();
System.out.println(b);
}
}
12File類list獲取功能
* A: File類list獲取功能
* a: 方法介紹
* String[] list():獲取到File構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄)
* 返回只有名字
* File[] listFiles():獲取到,File構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄)
* 返回的是目錄或者文件的全路徑
* static File[] listRoots(): 列出可用的文件系統根
* b: 案例代碼
public class FileDemo {
public static void main(String[] args) {
function_2();
}
public static void function_2(){
//獲取系統中的所有根目錄
File[] fileArr = File.listRoots();
for(File f : fileArr){
System.out.println(f);
}
}
/*
* File類的獲取功能
* File[] listFiles()
* 獲取到,File構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄)
* 返回的是目錄或者文件的全路徑
*/
public static void function_1(){
File file = new File("d:\\eclipse");
File[] fileArr = file.listFiles();
for(File f : fileArr){
System.out.println(f);
}
}
/*
* File類的獲取功能
* String[] list()
* 獲取到,File構造方法中封裝的路徑中的文件和文件夾名 (遍歷一個目錄)
* 返回只有名字
*/
public static void function(){
File file = new File("c:");
String[] strArr = file.list();
System.out.println(strArr.length);
for(String str : strArr){
System.out.println(str);
}
}
}
13文件過濾器
* A: 文件過濾器
* a: 作用
* 過濾一個目錄下的指定擴展名的文件,或者包含某些關鍵字的文件夾
* b: 方法介紹
* public String[] list(FilenameFilter filter)
* public File[] listFiles(FileFilter filter)
* C: 案例代碼
/*
* 自定義過濾器
* 實現FileFilter接口,重寫抽象方法
*/
public class MyFilter implements FileFilter{
public boolean accept(File pathname) {
/*
* pathname 接受到的也是文件的全路徑
* c:\\demo\\1.txt
* 對路徑進行判斷,如果是java文件,返回true,不是java文件,返回false
* 文件的後綴結尾是.java
*/
//String name = pathname.getName();
return pathname.getName().endsWith(".java");
}
}
/*
* File類的獲取,文件獲取過濾器
* 遍歷目錄的時候,可以根據需要,只獲取滿足條件的文件
* 遍歷目錄方法 listFiles()重載形式
* listFiles(FileFilter filter)接口類型
* 傳遞FileFilter接口的實現類
* 自定義FileFilter接口實現類,重寫抽象方法,
* 接口實現類對象傳遞到遍歷方法listFiles
*/
public class FileDemo1 {
public static void main(String[] args) {
File file = new File("c:\\demo");
File[] fileArr = file.listFiles(new MyFilter());
for(File f : fileArr){
System.out.println(f);
}
}
}
14文件過濾器_原理分析
* A:文件過濾器_原理分析
* listFiles()遍歷目錄的同時,獲取到了文件名全路徑,調用過濾器的方法accept,將獲取到的路徑傳遞給accept方法的參數pathname
* accept方法接收了參數pathname,參數是listFiles傳遞來的
* 在accept方法中,進行判斷,如果這個路徑是Java文件,返回true,走着返回false
* 一旦方法返回了true
* listFiles將路徑保存到File數組中
15遞歸遍歷全目錄
* A: 遞歸遍歷全目錄
* a: 案例代碼
/*
* 對一個目錄的下的所有內容,進行完全的遍歷
* 編程技巧,方法的遞歸調用,自己調用自己
*/
public class FileDemo {
public static void main(String[] args) {
File dir = new File("d:\\eclipse");
getAllDir(dir);
}
/*
* 定義方法,實現目錄的全遍歷
*/
public static void getAllDir(File dir){
System.out.println(dir);
//調用方法listFiles()對目錄,dir進行遍歷
File[] fileArr = dir.listFiles();
for(File f : fileArr){
//判斷變量f表示的路徑是不是文件夾
if(f.isDirectory()){
//是一個目錄,就要去遍歷這個目錄
//本方法,getAllDir,就是給個目錄去遍歷
//繼續調用getAllDir,傳遞他目錄
getAllDir(f);
}else{
System.out.println(f);
}
}
}
}
16遞歸概念和注意事項
* A:遞歸概念和注意事項
* a: 遞歸概念
* 遞歸,指在當前方法內調用自己的這種現象
* 遞歸分爲兩種,直接遞歸和間接遞歸
* 直接遞歸稱爲方法自身調用自己。間接遞歸可以A方法調用B方法,B方法調用C方法,C方法調用A方法
* b: 注意事項
* 遞歸一定要有出口, 必須可以讓程序停下
* 遞歸次數不能過多
* 構造方法,禁止遞歸
17遞歸求和計算
* A: 遞歸求和計算
* a: 題目分析
* 1+2+3+...+(n-1)+n:求1到n的和
* 總結規律:1到n的和等於1到(n-1)的和再加n
* getSum(n-1)+ n
* 遞歸出口:getSum(1) return 1;
* b: 案例代碼
/*
* 方法的遞歸調用
* 方法自己調用自己
* 適合於,方法中運算的主體不變,但是運行的時候,參與運行的方法參數會變化
* 注意:
* 遞歸一定要有出口, 必須可以讓程序停下
* 遞歸次數不能過多
* 構造方法,禁止遞歸
*/
public class DiGuiDemo {
public static void main(String[] args) {
int sum = getSum(3);
System.out.println(sum);
}
/*
* 計算 1+2+3+100和 = 5050
* 計算規律:
* n+(n-1)+(n-2)
* 100+(100-1)+(99-1)+...1
*/
public static int getSum(int n){
if( n == 1)
return 1;
return n + getSum(n-1);
}
}
18遞歸求階乘
* A: 遞歸求和計算
* a: 題目分析
* 5!=5*4*3*2*1
* =5*4!
* 4!=4*3!
* 3!=3*2!
* 2!=2*1!
* 1!=1
* n!=n*(n-1)!
* 遞歸出口:n*getJieCheng(n-1): getJieCheng(1) return 1;
* b: 案例代碼
/*
* 方法的遞歸調用
* 方法自己調用自己
* 適合於,方法中運算的主體不變,但是運行的時候,參與運行的方法參數會變化
* 注意:
* 遞歸一定要有出口, 必須可以讓程序停下
* 遞歸次數不能過多
* 構造方法,禁止遞歸
*/
public class DiGuiDemo {
public static void main(String[] args) {
System.out.println(getJieCheng(5));
}
/*
* 計算階乘 5!
* 5*4*3*2*1
*/
public static int getJieCheng(int n){
if ( n == 1)
return 1;
return n * getJieCheng(n-1);
}
}
19遞歸計算斐波那契數列
* A: 遞歸計算斐波那契數列
* a:題目分析
* 1 1 2 3 5 8 13 21
* 從第三項開始,後面的每一項都等於前面兩項的和,第一項和第二項的值爲1,作爲程序的出口
* b: 案例代碼
/*
* 方法的遞歸調用
* 方法自己調用自己
* 適合於,方法中運算的主體不變,但是運行的時候,參與運行的方法參數會變化
* 注意:
* 遞歸一定要有出口, 必須可以讓程序停下
* 遞歸次數不能過多
* 構造方法,禁止遞歸
*/
public class DiGuiDemo {
public static void main(String[] args) {
System.out.println(getFBNQ(12));
}
/*
* 方法遞歸,計算斐波那契數列
*
*/
public static int getFBNQ(int month){
if( month == 1)
return 1;
if( month == 2)
return 1;
return getFBNQ(month-1)+getFBNQ(month-2);
}
}
20遍歷目錄下的所有java文件
* A: 遍歷目錄下的所有java文件
* a: 案例代碼
public class MyJavaFilter implements FileFilter {
public boolean accept(File pathname) {
//判斷獲取的是目錄,直接返回true
if(pathname.isDirectory())
return true;
return pathname.getName().toLowerCase().endsWith(".java");
}
}
/*
* 遍歷目錄,獲取目錄下的所有.java文件
* 遍歷多級目錄,方法遞歸實現
* 遍歷的過程中,使用過濾器
*/
public class FileDemo1 {
public static void main(String[] args) {
getAllJava(new File("c:\\demo"));
// new File("c:\\demo").delete();
}
/*
* 定義方法,實現遍歷指定目錄
* 獲取目錄中所有的.java文件
*/
public static void getAllJava(File dir){
//調用File對象方法listFiles()獲取,加入過濾器
File[] fileArr = dir.listFiles(new MyJavaFilter());
for(File f : fileArr){
//對f路徑,判斷是不是文件夾
if(f.isDirectory()){
//遞歸進入文件夾遍歷
getAllJava(f);
}else{
System.out.println(f);
}
}
}
}
01輸入和輸出
* A:輸入和輸出
* a: 參照物
* 到底是輸入還是輸出,都是以Java程序爲參照
* b: Output
* 把內存中的數據存儲到持久化設備上這個動作稱爲輸出(寫)Output操作
* 程序到文件稱爲輸出
* c: Input
* 把持久設備上的數據讀取到內存中的這個動作稱爲輸入(讀)Input操作
* 文件到程序稱爲輸入
* d: IO操作
* 把上面的這種輸入和輸出動作稱爲IO操作
02字節輸出流OutputStream
* A: 字節輸出流OutputStream
* a.概念
* IO流用來處理設備之間的數據傳輸
* Java對數據的操作是通過流的方式
* Java用於操作流的類都在IO包中
* 流按流向分爲兩種:輸入流,輸出流。
* 流按操作類型分爲兩種:
* 字節流 : 字節流可以操作任何數據,因爲在計算機中任何數據都是以字節的形式存儲的
* 字符流 : 字符流只能操作純字符數據,比較方便。
* b.IO流常用父類
* 字節流的抽象父類:
* InputStream
* OutputStream
* 字符流的抽象父類:
* Reader
* Writer
* c.IO程序書寫
* 使用前,導入IO包中的類
* 使用時,進行IO異常處理
* 使用後,釋放資源
* d: 方法介紹
* void close(): 關閉此輸出流並釋放與此流有關的所有系統資源。
* void write(byte[] b): 將 b.length 個字節從指定的 byte 數組寫入此輸出流
* void write(byte[] b, int off, int len) :將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
* abstract void write(int b) : 將指定的字節寫入此輸出流。
03字節輸出流FileOutputStream寫字節
* A: 字節輸出流FileOutputStream寫字節
* a: FileOutputStream
* 寫入數據文件,學習父類方法,使用子類對象
* b: FileOutputStream構造方法
* 作用:綁定輸出的輸出目的
* FileOutputStream(File file)
* 創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流。
* FileOutputStream(File file, boolean append)
* 創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流,以追加的方式寫入。
* FileOutputStream(String name)
* 創建一個向具有指定名稱的文件中寫入數據的輸出文件流。
* FileOutputStream(String name, boolean append)
* 創建一個向具有指定 name 的文件中寫入數據的輸出文件流,以追加的方式寫入。
* c: 流對象使用步驟
* 1. 創建流子類的對象,綁定數據目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
* d: 注意事項
* 流對象的構造方法,可以創建文件,如果文件存在,直接覆蓋
* e: 案例代碼
/*
* FileOutputStream
* 寫入數據文件,學習父類方法,使用子類對象
*
* 子類中的構造方法: 作用:綁定輸出的輸出目的
* 參數:
* File 封裝文件
* String 字符串的文件名
*
* 流對象使用步驟
* 1. 創建流子類的對象,綁定數據目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
*
* 流對象的構造方法,可以創建文件,如果文件存在,直接覆蓋
*/
public class FileOutputStreamDemo {
public static void main(String[] args)throws IOException {
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流對象的方法write寫數據
//寫1個字節
fos.write(97);
//關閉資源
fos.close();
}
}
04字節輸出流FileOutputStream寫字節數組
* A: 字節輸出流FileOutputStream寫字節數組
* a: 方法介紹
* void write(byte[] b): 將 b.length 個字節從指定的 byte 數組寫入此輸出流
* void write(byte[] b, int off, int len) :將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
* b: 案例代碼
/*
* FileOutputStream
* 寫入數據文件,學習父類方法,使用子類對象
*
* 子類中的構造方法: 作用:綁定輸出的輸出目的
* 參數:
* File 封裝文件
* String 字符串的文件名
*
* 流對象使用步驟
* 1. 創建流子類的對象,綁定數據目的
* 2. 調用流對象的方法write寫
* 3. close釋放資源
*
* 流對象的構造方法,可以創建文件,如果文件存在,直接覆蓋
*/
public class FileOutputStreamDemo {
public static void main(String[] args)throws IOException {
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流對象的方法write寫數據
//寫字節數組
byte[] bytes = {65,66,67,68};
fos.write(bytes);
//寫字節數組的一部分,開始索引,寫幾個
fos.write(bytes, 1, 2);
//寫入字節數組的簡便方式
//寫字符串
fos.write("hello".getBytes());
//關閉資源
fos.close();
}
}
05文件的續寫和換行符號
* A: 文件的續寫和換行符號
* a: 文件的續寫
* FileOutputStream構造方法, 的第二個參數中,加入true
* b: 換行符號
* 在文件中,寫入換行,符號換行 \r\n
* \r\n 可以寫在上一行的末尾, 也可以寫在下一行的開頭
* c: 案例代碼
/*
* FileOutputStream 文件的續寫和換行問題
* 續寫: FileOutputStream構造方法, 的第二個參數中,加入true
* 在文件中,寫入換行,符號換行 \r\n
* \r\n 可以寫在上一行的末尾, 也可以寫在下一行的開頭
*/
public class FileOutputStreamDemo1 {
public static void main(String[] args)throws IOException {
File file = new File("c:\\b.txt");
FileOutputStream fos = new FileOutputStream(file,true);
fos.write("hello\r\n".getBytes());
fos.write("world".getBytes());
fos.close();
}
}
06IO中的異常處理
* A: IO中的異常處理
* a:IO流的異常處理
* try catch finally
* b: 細節
* 1. 保證流對象變量,作用域足夠
* 2. catch裏面,怎麼處理異常
* 輸出異常的信息,目的看到哪裏出現了問題
* 停下程序,從新嘗試
* 3. 如果流對象建立失敗了,需要關閉資源嗎
* new 對象的時候,失敗了,沒有佔用系統資源
* 釋放資源的時候,對流對象判斷null
* 變量不是null,對象建立成功,需要關閉資源
* c: 案例代碼
public class FileOutputStreamDemo3 {
public static void main(String[] args) {
//try 外面聲明變量,try 裏面建立對象
FileOutputStream fos = null;
try{
fos = new FileOutputStream("s:\\a.txt");
fos.write(100);
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件寫入失敗,重試");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("關閉資源失敗");
}
}
}
}
07字節輸入流InputStream
* A: 字節輸入流InputStream
* a: 方法介紹
* abstract int read() :
* 從輸入流中讀取數據的下一個字節。
* int read(byte[] b)
* 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
* int read(byte[] b, int off, int len)
* 將輸入流中最多 len 個數據字節讀入 byte 數組。
* void close()
* 關閉此輸入流並釋放與該流關聯的所有系統資源。
* b: 案例代碼
/*
* 字節輸入流
* java.io.InputStream 所有字節輸入流的超類
* 作用: 讀取任意文件,每次只讀取1個字節
* 讀取的方法 read
* int read() 讀取1個字節
* int read(byte[] b) 讀取一定量的字節,存儲到數組中
*/
public class InputStreamDemo {
}
08字節輸入流FileInputStream讀取字節
* A: 字節輸入流FileInputStream讀取字節
* a: 方法介紹
* abstract int read() :
* 從輸入流中讀取數據的下一個字節,返回-1表示文件結束
* int read(byte[] b)
* 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
* 讀入緩衝區的字節總數,如果因爲已經到達文件末尾而沒有更多的數據,則返回 -1。
* int read(byte[] b, int off, int len)
* 將輸入流中最多 len 個數據字節讀入 byte 數組。
* void close()
* 關閉此輸入流並釋放與該流關聯的所有系統資源。
* b: 案例代碼
/*
* FileInputStream讀取文件
*
* 構造方法: 爲這個流對象綁定數據源
*
* 參數:
* File 類型對象
* String 對象
* 輸入流讀取文件的步驟
* 1. 創建字節輸入流的子類對象
* 2. 調用讀取方法read讀取
* 3. 關閉資源
*
* read()方法,
* read()執行一次,就會自動讀取下一個字節
* 返回值,返回的是讀取到的字節, 讀取到結尾返回-1
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException{
FileInputStream fis = new FileInputStream("c:\\a.txt");
//讀取一個字節,調用方法read 返回int
//使用循環方式,讀取文件, 循環結束的條件 read()方法返回-1
int len = 0;//接受read方法的返回值
while( (len = fis.read()) != -1){
System.out.print((char)len);
}
//關閉資源
fis.close();
}
}
/*
* int i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
*/
09字節輸入流FileInputStream讀取字節數組
* A: 字節輸入流FileInputStream讀取字節數組
* a: 方法介紹
* int read(byte[] b)
* 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
* 讀入緩衝區的字節總數,如果因爲已經到達文件末尾而沒有更多的數據,則返回 -1。
* int read(byte[] b, int off, int len)
* 將輸入流中最多 len 個數據字節讀入 byte 數組。
* b: 案例代碼
/*
* FileInputStream讀取文件
* 讀取方法 int read(byte[] b) 讀取字節數組
* 數組作用: 緩衝的作用, 提高效率
* read返回的int,表示什麼含義 讀取到多少個有效的字節數
*/
public class FileInputStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("c:\\a.txt");
// 創建字節數組
byte[] b = new byte[2];
int len = fis.read(b);
System.out.println(new String(b));// ab
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// cd
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// 1
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// -1
fis.close();
}
}
10字節輸入流FileInputStream讀取字節數組的實現原理
* A:字節輸入流FileInputStream讀取字節數組的實現原理
* a: 原理
* 參見day23_source文件夾中的"讀取數組的原理.jpg"
* b: 案例代碼
public class FileInputStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("c:\\a.txt");
//創建字節數組
byte[] b = new byte[1024];
int len = 0 ;
while( (len = fis.read(b)) !=-1){
System.out.print(new String(b,0,len));
}
fis.close();
}
}
11文件複製原理
* A: 文件複製原理
* a: 見day23_source/文件複製原理.jpg
12字節流複製文件讀取單個字節
* A: 字節流複製文件讀取單個字節
* a: 案例代碼
/*
* 將數據源 c:\\a.txt
* 複製到 d:\\a.txt 數據目的
* 字節輸入流,綁定數據源
* 字節輸出流,綁定數據目的
*
* 輸入,讀取1個字節
* 輸出,寫1個字節
*/
public class Copy {
public static void main(String[] args) {
//定義兩個流的對象變量
FileInputStream fis = null;
FileOutputStream fos = null;
try{
//建立兩個流的對象,綁定數據源和數據目的
fis = new FileInputStream("c:\\t.zip");
fos = new FileOutputStream("d:\\t.zip");
//字節輸入流,讀取1個字節,輸出流寫1個字節
int len = 0 ;
while((len = fis.read())!=-1){
fos.write(len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件複製失敗");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
}
}
13字節流複製文件讀取字節數組
* A: 字節流複製文件讀取字節數組
* a: 案例代碼
/*
* 字節流複製文件
* 採用數組緩衝提高效率
* 字節數組
* FileInputStream 讀取字節數組
* FileOutputStream 寫字節數組
*/
public class Copy_1 {
public static void main(String[] args) {
long s = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try{
fis = new FileInputStream("c:\\t.zip");
fos = new FileOutputStream("d:\\t.zip");
//定義字節數組,緩衝
byte[] bytes = new byte[1024*10];
//讀取數組,寫入數組
int len = 0 ;
while((len = fis.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件複製失敗");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
long e = System.currentTimeMillis();
System.out.println(e-s);
}
}
14編碼表
* A: 編碼表
* a: 定義:
* 生活中字符和計算機二進制的對應關係表,就是編碼表
* b: 分類
* 1、ascii: 一個字節中的7位就可以表示。對應的字節都是正數。0-xxxxxxx
* 2、iso-8859-1:拉丁碼錶 latin,用了一個字節用的8位。1-xxxxxxx 負數。
* 3、GB2312:簡體中文碼錶。包含6000-7000中文和符號。用兩個字節表示。兩個字節第一個字節是負數,第二個字節可能是正數
* GBK:目前最常用的中文碼錶,2萬的中文和符號。用兩個字節表示,其中的一部分文字,第一個字節開頭是1,第二字節開頭是0
* GB18030:最新的中文碼錶,目前還沒有正式使用。
* 4、unicode:國際標準碼錶:無論是什麼文字,都用兩個字節存儲。
* Java中的char類型用的就是這個碼錶。char c = 'a';佔兩個字節。
* Java中的字符串是按照系統默認碼錶來解析的。簡體中文版 字符串默認的碼錶是GBK。
* 5、UTF-8:基於unicode,一個字節就可以存儲數據,不要用兩個字節存儲,而且這個碼錶更加的標準化,在每一個字節頭加入了編碼信息(後期到api中查找)。
* 6、能識別中文的碼錶:GBK、UTF-8;正因爲識別中文碼錶不唯一,涉及到了編碼解碼問題。
* 對於我們開發而言;常見的編碼 GBK UTF-8 ISO-8859-1
* 文字--->(數字) :編碼。 “abc”.getBytes() byte[]
* (數字)--->文字 : 解碼。 byte[] b={97,98,99} new String(b)
15字符輸出流寫文本FileWriter類
* A: 字符輸出流寫文本FileWriter類
* a: 方法介紹
* void write(int c)
* 寫入單個字符
* void write(String str)
* 寫入字符串
* void write(String str, int off, int len)
* 寫入字符串的某一部分
* void write(char[] cbuf)
* 寫入字符數組
* abstract void write(char[] cbuf, int off, int len)
* 寫入字符數組的某一部分
* b: 案例代碼
/*
* 字符輸出流
* java.io.Writer 所有字符輸出流的超類
* 寫文件,寫文本文件
*
* 寫的方法 write
* write(int c) 寫1個字符
* write(char[] c)寫字符數組
* write(char[] c,int,int)字符數組一部分,開始索引,寫幾個
* write(String s) 寫入字符串
*
* Writer類的子類對象 FileWriter
*
* 構造方法: 寫入的數據目的
* File 類型對象
* String 文件名
*
* 字符輸出流寫數據的時候,必須要運行一個功能,刷新功能
* flush()
*/
public class WriterDemo {
public static void main(String[] args) throws IOException{
FileWriter fw = new FileWriter("c:\\1.txt");
//寫1個字符
fw.write(100);
fw.flush();
//寫1個字符數組
char[] c = {'a','b','c','d','e'};
fw.write(c);
fw.flush();
//寫字符數組一部分
fw.write(c, 2, 2);
fw.flush();
//寫如字符串
fw.write("hello");
fw.flush();
fw.close();
}
}
16字符輸入流讀取文本FileReader類
* A: 字符輸入流讀取文本FileReader類
* a: 方法介紹
* int read()
* 讀取單個字符
* int read(char[] cbuf)
* 將字符讀入數組
* abstract int read(char[] cbuf, int off, int len)
* 將字符讀入數組的某一部分。
* b: 案例代碼
/*
* 字符輸入流讀取文本文件,所有字符輸入流的超類
* java.io.Reader
* 專門讀取文本文件
*
* 讀取的方法 : read()
* int read() 讀取1個字符
* int read(char[] c) 讀取字符數組
*
* Reader類是抽象類,找到子類對象 FileReader
*
* 構造方法: 綁定數據源
* 參數:
* File 類型對象
* String文件名
*/
public class ReaderDemo {
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("c:\\1.txt");
/*int len = 0 ;
while((len = fr.read())!=-1){
System.out.print((char)len);
}*/
char[] ch = new char[1024];
int len = 0 ;
while((len = fr.read(ch))!=-1){
System.out.print(new String(ch,0,len));
}
fr.close();
}
}
17flush方法和close方法區別
* A: flush方法和close方法區別
*a: flush()方法
* 用來刷新緩衝區的,刷新後可以再次寫出,只有字符流才需要刷新
*b: close()方法
* 用來關閉流釋放資源的的,如果是帶緩衝區的流對象的close()方法,不但會關閉流,還會再關閉流之前刷新緩衝區,關閉後不能再寫出
18字符流複製文本文件
* A: 字符流複製文本文件
* a: 案例代碼
/*
* 字符流複製文本文件,必須文本文件
* 字符流查詢本機默認的編碼表,簡體中文GBK
* FileReader讀取數據源
* FileWriter寫入到數據目的
*/
public class Copy_2 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("c:\\1.txt");
fw = new FileWriter("d:\\1.txt");
char[] cbuf = new char[1024];
int len = 0 ;
while(( len = fr.read(cbuf))!=-1){
fw.write(cbuf, 0, len);
fw.flush();
}
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("複製失敗");
}finally{
try{
if(fw!=null)
fw.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}finally{
try{
if(fr!=null)
fr.close();
}catch(IOException ex){
throw new RuntimeException("釋放資源失敗");
}
}
}
}
}