第4章Java的IO流和異常處理_第1頁
第4章Java的IO流和異常處理_第2頁
第4章Java的IO流和異常處理_第3頁
第4章Java的IO流和異常處理_第4頁
第4章Java的IO流和異常處理_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

2023/2/6第四章Java的I/O流和異常處理本章主要內容:Java中常用I/O流、方法及其應用,包括:SystemI/O類、字節(jié)流和字符流處理,以及對象序列化,Java中的異常處理機制及異常處理.2023/2/64.1I/O流概述 4.2SystemI/O類和Scanner類

4.2.1SystemI/O類 4.2.2Scanner類 4.3文件類

4.3.1使用File類訪問文件系統(tǒng) 4.3.2隨機文件讀寫 4.4字節(jié)級輸入輸出流

4.4.1數(shù)據(jù)輸入輸出流 4.4.2文件輸入輸出流 4.4.3緩沖輸入輸出流 4.4.4管道輸入輸出流 4.4.5格式化輸出流 4.5字符級輸入輸出類 4.5.1字符輸入輸出類 4.5.2緩沖讀寫類 4.5.3文件讀寫類 4.5.4格式化寫類 4.6對象序列化 4.6.1對象輸入流 4.6.2對象輸出流 4.7異常處理

4.7.1Java中定義的異常 4.7.2異常類的層次結構 4.7.3捕獲異常 4.7.4異常處理的嵌套 4.7.5自定義的異常和使用

第四章Java的I/O流和異常處理2023/2/64.1I/O流的概念流是指流動的數(shù)據(jù)序列,可分為輸入流和輸出流。在程序設計語言中,流式輸入輸出是一種常見的輸入輸出方式。它是一個比文件更加廣泛的概念。輸入流將外部數(shù)據(jù)輸入到計算機。例如從鍵盤,掃描儀,攝像頭,網絡等數(shù)據(jù)源輸入數(shù)據(jù)。輸出流將計算機中的數(shù)據(jù)輸出到外部設備。例如將要打印的信息發(fā)送到打印機,將計算的結果顯示到輸出設備上。流的特點:所有數(shù)據(jù)的傳輸都按照數(shù)據(jù)序列的順序進行。每個數(shù)據(jù)依序被讀入或寫出,Java中采用類的方式實現(xiàn)I/O流。2023/2/6java.io包中的類,可分為字節(jié)級輸入輸出流、字符級輸入輸出流和對象級輸入輸出流。相關類層次如圖所示:InputStream和OutputStream是Java語言中最基本的兩個輸入輸出類。其他所有字節(jié)輸入輸出流類都繼承自這兩個基類。這兩個類都是抽象類,都繼承自Object類,因而不能創(chuàng)建它們的實例,只能使用它們的子類.

2023/2/6讀取下一個字節(jié),-1表示輸入結束abstractintread();

讀取數(shù)據(jù)存入緩沖區(qū)b中。返回讀取的字節(jié)個數(shù),-1表示結束intread(byteb[]);讀取最多l(xiāng)en字節(jié)數(shù)據(jù)存入緩沖區(qū)b中,并從第off個位置存放intread(byteb[],intoff,intlen);

返回可直接讀取字節(jié)個數(shù)intavailable();從輸入流中忽略n個字節(jié)的數(shù)據(jù),返回實際忽略的字節(jié)個數(shù)longskip(longn);關閉輸入流

close();InputStream的主要方法2023/2/6寫一字節(jié),整數(shù)b的低字節(jié),其高3個字節(jié)被忽略

abstractvoidwrite(intb);把緩沖區(qū)b中的全部數(shù)據(jù)寫入輸出流

voidwrite(byteb[]);

把緩沖區(qū)b中從b[off]開始的len個字節(jié)的數(shù)據(jù)寫入輸出流

voidwrite(byteb[],intoff,intlen);

刷新輸出流,強制輸出所有被緩存的字節(jié)voidflush();關閉輸出流voidclose();在實際應用中,常用InputStream和OutputStream類的引用指向它們的具體實現(xiàn)的子類對象.OutputStream的方法2023/2/64.2SystemI/O類和Scanner類 SystemI/O類稱為標準輸入輸出類。在Java中標準的輸入設備是鍵盤,標準的輸出設備是終端或顯示器。他們分別對應System類中的變量in,out和err。這三個類變量(對象類型)在System類中的聲明如下:

publicstaticfinalInputStreamin; publicstaticfinalPrintStreamout; publicstaticfinalPrintStreamerr;對于PrintStream類最常用的兩個方法為:

publicvoidprint();//輸出一行字符串 publicvoidprintln();//輸出后并換行例如,輸入后立即輸出這個數(shù):bytebs=System.in.read();System.out.println(bs);2023/2/6Scanner類Scanner類是可用正則表達式來分析基本類型和字符串的簡單文本掃描器。它使用分隔符模式將其輸入分解為標記,再使用next方法將得到的標記轉換為不同類型的值.例如,讀入一個整數(shù): Scannersc=newScanner(System.in); inti=sc.nextInt();

下面舉例說明.【例4.1】SystemI/O類和Scanner類2023/2/6注意,輸入流的結束程序運行結果?2023/2/64.3文件類1.使用File類處理有關文件和目錄訪問的File類。實現(xiàn)新建、刪除、獲取屬性等功能。File類方法如表所示:

Filefile=newFile("c:\\windows\\explorer.exe");System.out.println(file.getName());/////////////////////////////explorer.exeSystem.out.println(file.getPath());////////////c:\windows\explorer.exeSystem.out.println(file.getParentFile());////////////////////////////////////////////////////////////////////////"c:\windows"2023/2/62023/2/6例如,利用File對象創(chuàng)建文件和目錄注意,new操作一定成功嗎?程序運行結果?2023/2/62.使用RandomAccessFile類Java提供了RandomAccessFile類,它的實例能同時支持隨機存取文件的讀寫操作,每讀取一個字節(jié),指針后移一個字節(jié);寫操作也在指針位置寫字節(jié),然后指針后移到所寫字節(jié)之后.

RandomAccessFile類有兩個構造方法:RandomAccessFile(Stringfilename,Stringmode);RandomAccessFile(Filefile,Stringmode);

其中,mode值可以是:2023/2/6RandomAccessFile類的方法【例4.2】RandomAccessFile類下面舉例說明.2023/2/6注意,寫入了基本類型數(shù)據(jù)程序運行結果?2023/2/64.4字節(jié)級輸入輸出流1.數(shù)據(jù)輸入輸出流(DataInputStream,DataOutputStream)讀取\寫入Java基本類型的數(shù)據(jù).這些類型在文件中的表示方式與其在內存中的一樣,無需轉換.其構造方法和一般方法分別是:2023/2/62.文件輸入輸出流(FileInputStream,FileOutputStream)分別繼承于InputStream類和OutputStream類。打開本地主機上的文件,并進行順序的讀/寫。它們的構造方式是:通常與其他字節(jié)輸入輸出類結合使用.下面舉例說明.【例4.3】DataInputStream/DataOutputStream類通過類File對象或者一個表示文件名的字符串可以生成文件輸入/輸出流對象,同時文件被打開,然后進行文件讀/寫.2023/2/6數(shù)據(jù)輸入輸出流與文件輸入輸出流結合舉例注意,寫入了基本類型數(shù)據(jù)程序運行結果?2023/2/63.緩沖輸入輸出流(BufferedInputStream,BufferedOutputStream)當創(chuàng)建一個BufferedInputStream類的實例時,也就創(chuàng)建了一個內部緩沖數(shù)組,缺省使用32字節(jié)大小的緩沖區(qū).當讀取數(shù)據(jù)時,數(shù)據(jù)按塊讀入緩沖區(qū),其后的讀操作則直接訪問緩沖區(qū)。當寫入數(shù)據(jù)時,首先寫入緩沖區(qū),當緩沖區(qū)滿時,其中的數(shù)據(jù)寫入所連接的輸出流。使用方法flush()可以強制將緩沖區(qū)的內容全部寫入輸出流。下面舉例說明.【例4.4】BufferedInputStream/BufferedOutputStream類2023/2/6程序功能?2023/2/64.管道輸入輸出流(PipedInputStream,PipedOutputStream)這兩個流用于進程之間的通信。一個PipedInputStream必須連接一個PipedOutputStream,反之亦然。下面是這兩個對象建立聯(lián)系的方法:

2023/2/6管道用來把一個程序、線程或代碼塊的輸出連接到另一個程序、線程或代碼塊的輸入.管道輸入流作為一個通信管道的接收端,管道輸出流作為發(fā)送端.在使用管道之前,管道輸出流和管道輸入流必須進行連接.2023/2/65.格式化輸出流(PrintStream)PrintStream具有在System文件句柄使用過的System.out所有的格式化性能。PrintStream有以下兩個構造方法:PrintStream(OutputStreamoutputStream)PrintStream(OutputStreamoutputStream,booleanflushOnNewline)注意,在上述這些字節(jié)輸入輸出流中,所讀出的數(shù)據(jù)應該是由相應的寫入類寫入的.2023/2/6面向字節(jié)級I/O編程的一般步驟是:

(1)磁盤文件作為FileInputStream的構造方法的參數(shù),實例化一個FileInputStream對象。

(2)FileInputStream對象作為DataInputStream的構造方法的參數(shù)。

(3)然后就可以使用InputStream類中的方法,進行字節(jié)輸入流的操作。例如,read()方法及其重載方法,available(),skip(),close()等?;蛘?,用FileInputStream對象作為BufferedInputStream的構造方法的參數(shù),然后使用read()等方法進行讀操作。對于字節(jié)級輸出流也具有相對應的類和方法。2023/2/6在Java中,定義了專門用于處理字符數(shù)據(jù)輸入輸出的抽象類Reader和Writer類,它們與InputStream和Output-Stream類很相似,也有很多子類。1.Reader類和Writer類它們是所有字符流的超類,它們是直接繼承Object類的抽象類,可讀寫16位的字符流。類層次結構如圖:4.5字符輸入輸出類2023/2/6字節(jié)流、字符流區(qū)別:字節(jié)流按字節(jié)來處理數(shù)據(jù),而文本數(shù)據(jù)可能采用各種不同的字符編碼方式,可能是單字節(jié)字符,也可能是多字節(jié)字符,因而要借助于字符流來處理文本類信息。字節(jié)流不能直接操作Unicode字符。在Unicode字符中,一個漢字被看成一個字符。2023/2/6BufferedReader從字符輸入流中讀取文本,該輸入流的指向必須是一個Reader流(底層流),由該底層流將數(shù)據(jù)讀入緩沖區(qū),以后BufferReader類創(chuàng)建的流對象就從緩沖區(qū)中讀取數(shù)據(jù)。其構造方法如下:publicBufferedReader(Readerin);BufferedWriter類用來創(chuàng)建一個字符輸出流。BufferWriter流將數(shù)據(jù)寫入緩沖區(qū),由底層流(像FileWriter流)寫到最終目的地。其構造方法如下:

publicBufferedWriter(Writerout);問題,當創(chuàng)建這些對象時,其傳入參數(shù)可以是什么類型?2.緩沖讀寫類(BufferedReader,BufferedWriter)2023/2/63.文件讀寫類(FileReader,FileWriter)FileReader類用來讀取字符數(shù)據(jù),其構造方法是:publicFileReader(Stringfilename)throwsFileNotFoundExceptionpublicFileReader(Filefile)throwsFileNotFoundException

FileWriter類用來寫入字符數(shù)據(jù),其構造方法是:

publicFileWriter(StringfileName)throwsIOExceptionpublicFileWriter(Filefile)throwsIOException例如,

FileReaderfr=newFileReader(“temp.txt”);BufferReaderbr=newBufferReader(fr);Strings=br.readLine();【例4.5】BufferedReader/BufferedWriter類實際文件FileReader類BufferedReader類實際文件FileWriter類BufferedWriter類2023/2/62023/2/6利用文件讀寫類實現(xiàn)文件拷貝與之前利用緩沖輸入輸出流進行文件拷貝進行對照程序功能?2023/2/6Java提供了一個將字節(jié)流轉換成字符流的類InputStreamReader。反之,OutputStreamWriter類.它們的構造方法是:

publicInputStreamReader(InputStreamin);

publicOutputStreamWriter(OutputStream

out)例如,BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));因此,BufferedReader類的對象br具有從字節(jié)數(shù)據(jù)中讀出字符數(shù)據(jù)的能力.【例4.6】InputStreamReader類2023/2/6例如,從鍵盤讀入一行數(shù)字字符注意,用到了封裝器類的方法程序運行結果?2023/2/6流結束的判斷read()

返回-1。readXXX() readInt()、readByte()、readLong()、readDouble()等; 產生EOFException。readLine()

返回null。2023/2/6面向字符級I/O編程的一般步驟是:(l)將字符文件作為參數(shù)分別構造FileReader和FileWriter對象。(2)以FileReader對象作為參數(shù)構造BufferedReader對象。(3)以FileWriter對象作為參數(shù)構造PrintWriter對象。(4)調用BufferedReader對象的readLine()方法讀取字符數(shù)據(jù)或者按照分隔符讀取某個記錄的每個字段。(5)調用PrintWriter對象的println()方法寫入字符數(shù)據(jù)或記錄。對于字符級輸出流也具有相應的類和方法。2023/2/6對象序列化(Serialization)將那些實現(xiàn)了Serializable接口的對象轉換成一個字節(jié)序列,并且能夠將這個字節(jié)序列完全恢復為原來的對象,實現(xiàn)了對象的持久性。序列化以后的對象可以在網絡上傳輸,使得不同的計算機可以共享對象.只有實現(xiàn)了Serializable接口的類的對象才可以被串行化,即該對象就是序列化的對象。注意,Serializable接口中沒有任何的方法,實現(xiàn)該接口的類不需要實現(xiàn)額外的方法。4.6對象序列化2023/2/6ObjectInputStream類用于讀出由ObjectOutputStream寫入的對象,只有支持Serializable接口的對象才可以從這個流中讀出。其構造方法如下:

PublicObjectInputStream(InputStreamin)throwsIOExceptionObjectOutputStream類用于將已實現(xiàn)Serializable接口的對象寫入到輸出流中。其構造方法如下:

PublicObjectOutputStream(OutputStreamout)throwsIOException使用readObject(),writeObject方法可讀寫一個對象.對象輸入輸出流(ObjectInputStream,ObjectOutputStream)【例4.8】ObjectInputStream類和ObjectOutputStream類2023/2/6程序運行結果?程序代碼2023/2/6串行化的注意事項串行化能保存的元素 只能保存對象的非靜態(tài)成員變量,不能保存任何成員方法和靜態(tài)的成員變量,而且串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存。使用對象流把一個對象寫到文件時不僅保證該對象是序列化的,而且該對象的成員對象也必須是可序列化的。缺省的串行化機制,對象串行化首先寫入類和字段的信息,然后按照名稱的升序寫入其數(shù)值。如果想自己明確地控制這些數(shù)值的寫入順序和寫入種類,必須定義自己的讀取數(shù)據(jù)流的方式。就是在類的定義中重寫writeObject()和readObject()方法.2023/2/6異常:在程序運行過程中發(fā)生的錯誤,這些錯誤在編譯時無法發(fā)現(xiàn)。如數(shù)組下標越界,0作為除數(shù)等。Java中定義了很多異常類,每個異常類都代表了一種或者多種運行錯誤,包含了該運行錯誤的信息和處理錯誤的方法等內容。每個異常類都繼承自Exception類,如圖所示:4.7異常處理2023/2/6Java異常類的層次結構和繼承關系Error,一般指與JVM或動態(tài)加載等相關的問題,如虛擬機錯誤,動態(tài)鏈接失敗,系統(tǒng)崩潰等,這類錯誤一般被認為是無法恢復和不可捕捉的,將導致程序中斷.2023/2/6兩種處理異常的機制捕獲異常

當Java運行時系統(tǒng)得到一個異常對象時,它將會沿著方法的調用棧逐層回溯,尋找處理這一異常的代碼。尋找的對象從生成異常對象的代碼塊開始,沿著方法的調用棧逐層回溯,直到找到一個方法能夠處理這種類型的異常為止。運行時系統(tǒng)把當前異常對象交給這個方法進行處理,這一過程稱為捕獲(catch)異常。如果Java運行時系統(tǒng)找不到可以捕獲異常的方法,則運行時系統(tǒng)將終止,相應的Java程序也將退出。聲明拋出異常

如果一個方法并不知道如何處理所出現(xiàn)的異常,則可在方法聲明時,聲明拋出(throws)異常。這是一種消極的異常處理機制。2023/2/6在Java程序的執(zhí)行過程中,如果出現(xiàn)了異常事件,就會生成一個異常對象。異常對象可能是由正在運行的方法生成,也可能由Java虛擬機生成,其中包含一些信息指明異常事件的類型,以及當異常發(fā)生時程序的運行狀態(tài)等。其中,類RuntimeException代表運行時由JVM生成的異常,即在程序運行時發(fā)現(xiàn)的由Java解釋器引發(fā)的各種異常。例如,ArithmeticException,ArrayIndexOutOfBoundsException等.其他的為非運行時異常,是指能由編譯器在編譯時檢測是否發(fā)生在方法的執(zhí)行過程中的異常,例如,IOException,F(xiàn)ileNotFoundException等.java.lang,java.io和包中定義了很多異常類.Java編譯器要求Java程序必須捕捉或聲明拋出所有的非運行時異常。但對運行時異??梢圆蛔魈幚?。2023/2/6try-catch-finally語句塊

try{ //可能發(fā)生異常的語句或語句塊}catch(ExceptionType1name1){ //對ExceptionType1類型異常進行處理}catch(ExceptionType2name2){//對ExceptionType2類型異常進行處理}finally{ //強制執(zhí)行語句塊}Java異常處理語句2023/2/6try-catch-finally語句塊的執(zhí)行流程:(1)try塊中的語句沒有產生異常,在這種情況下,Java首先執(zhí)行try塊中的所有語句,然后執(zhí)行finally子句中的代碼,最后執(zhí)行try-catch-finally語句塊后面的語句。(2)try塊中的語句產生了異常,而且此異常在方法內被捕獲。此時,Java首先執(zhí)行try塊中的語句,直到產生異常,然后跳過此try中的后續(xù)語句,執(zhí)行捕捉此異常的catch塊中的語句,然后執(zhí)行finally子句中的語句。注意:無論try塊中是否出現(xiàn)異常,finally塊中的語句總是得到執(zhí)行.2023/2/6對多個異常進行處理時,程序會按照catch語句的排列順序匹配被捕捉的異常和每個catch語句的參數(shù),直到找到可以匹配的異常處理方法。多個catch語句的參數(shù)應該按照匹配范圍由窄到寬的順序排列。否則會引起以下編譯錯誤:“…catch”hasalreadybeencaught

即,如果寬類型的catch塊先于被執(zhí)行到就會導致那些在后面出現(xiàn)的窄類型catch塊永遠得不到執(zhí)行!2023/2/6異常的捕獲及其處理

1.可以在方法體中直接捕獲可能出現(xiàn)的異常。在列出多個異常類時由窄類型到寬類型依序排列。例如,

voidtestException{try{...}catch(IOExceptione){}catch(Exceptione){}}下面舉例予以說明.【例4.9】異常未捕獲和直接捕獲2023/2/6下面是未處理異常時的例子publicclasstestException{publicstaticvoidmain(String[]args){

intx,y,result;x=5;y=0;result=x/y;System.out.println(“這是一個測試字符串!");}}該程序的運行結果是:2023/2/6下面是增加異常處理時的例子publicclasstestException2{publicstaticvoidmain(String[]args){

intx=5,y=0,result;try{result=x/y;System.out.println(“發(fā)生異常時不會被執(zhí)行的語句!");}catch(Exceptione){System.out.println(e.toString());

}System.out.println(“這是一個測試字符串!");}}該程序的運行結果是:2023/2/6下面是完整的異常處理的情形該程序的運行結果是:如果執(zhí)行return語句呢?2023/2/6下面是捕捉多個catch塊的情形該程序的運行結果是:2023/2/6對多個異常進行處理時,程序會按照catch語句的排列順序匹配被捕捉的異常和每個catch語句的參數(shù),直到找到可以匹配的異常處理方法。多個catch語句的參數(shù)應該按照匹配范圍由窄到寬的順序排列。否則會引起以下編譯錯誤:“…catch”hasalreadybeencaught

即,如果寬類型的catch塊先于被執(zhí)行到就會導致那些在后面出現(xiàn)的窄類型catch塊永遠得不到執(zhí)行!2023/2/62.方法聲明拋出異??梢栽诜椒ǖ亩x中利用throws關鍵字聲明該方法拋出異常的類型。把那些在方法中不關心或不方便處理的異常傳遞給上層調用處理。通常,方法的調用者會去捕獲這些異常。throws語法如下:voidmethodName()throwsExceptionType1,…,ExceptionTypen{

……

}下面舉例說明之.運行時異常需要捕獲嗎?【例4.10】聲明異常和間接捕獲2023/2/6程序運行結果?2023/2/64.異常處理的嵌套Java語言的try-catch語句可以嵌套,即在try塊中可以包含另外的try-catch語句。其格式如下:try{

try{…}catch(){…}}catch(){…}2023/2/6或者在finally子句包含try-catch語句雖然Java提供了異常的嵌套機制,除非處理過程中一定需要,否則不

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論