java 运行异常处理_Java编程异常处理和I/O流
重點: 1.在編寫程序時,要正確地使用捕獲例外和聲明拋出異常的兩種例外處理的方法。
2.遇到實際問題時,要根據需要正確使用各種輸入/輸出流,特別是對中文使用適當的字符輸入流。
3.正確使用對象串行化的方法。
難點:
1.如何使用Java中兩種異常處理機制,拋棄異常和聲明拋棄異常的區別與聯系。
2.處理字符流時,其構造方法的參數是一個字節流。
3.對象串行化的概念。
(一)處理異常
有的異常在編譯(輸入命令行)時出現,而有的異常是在運行時出現。
異常處理機制:捕獲異常(try-catch-finally)-積極機制、拋出異常(throw)-消極機制
異常類的層次:Throwable類中的Error、Exception類
Error類:LinkageError 動態鏈接失敗、VirtualMachineError 虛擬機錯誤、AWTError
Exception類:RuntimeException運行時異常(算術異常除0錯、數組下標越界等)、IOExcetpion(非運行時異常)、AWTError。。。
運行時的異常Java編譯器允許程序員不做處理,而非運行時的異常Java編譯器要求程序員必須進行捕獲或拋出異常的處理:
1.try-catch-finally語句:
try{......}
catch( ExceptionName1 e
){......}?//ExceptionName1
異常子類
catch( ExceptionName2 e
){......}?//ExceptionName2
異常父類
finally{......}
【注意】catch
語句的順序:
捕獲例外的順序和catch語句的順序有關,當捕獲到一個異常時,剩下的catch語句就不再進行匹配。因此,在安排catch語句的順序時,首先應該捕獲最特殊的異常,然后再逐漸一般化。也就是一般先安排子類,再安排父類。
通過finally語句為異常處理提供一個統一的出口,不論在try代碼塊中是否發生了異常事件,finally塊中的語句都會被執行。
2.throws聲明語句:
如果在一個方法中生成了一個異常,但是這一方法并不確切地知道該如何對這一異常事件進行處理,這時,一個方法就應該聲明拋棄異常,使得異常對象可以從調用棧向后傳播,直到有合適的方法捕獲它為止。
public int read ()?throws?IOException{
......
}
注意:throws子句中同時可以指明多個異常,之間由逗號隔開。例如:
public static void main(String
args[])?throws
IOException,IndexOutOfBoundsException?{…}
3.throws語句:IOException e=new
IOException();throw
e ; //注意:此處拋出的對象必須是異常實例,不可拋出其他。
(二)自定義異常類的使用:
自定義異常類必須是Throwable的直接或間接子類。
【注意】:一個方法所聲明拋出的異常是作為這個方法與外界交互的一部分而存在的。所以,方法的調用者必須了解這些異常,并確定如何正確的處理他們。
(三)I/O
流概述:
I/0流:輸入/輸出處理源(stream),比如從鍵盤讀取數據、從文件中讀取數據或向文件中寫數據等等。Jdk
提供了包java.io,其中包括一系列的類來實現輸入/輸出處理。
1.字節流:(byte)
從InputStream和OutputStream派生出來的一系列類。
◇ InputStream、OutputStream
◇ FileInputStream、FileOutputStream
◇ PipedInputStream、PipedOutputStream
◇ ByteArrayInputStream、ByteArrayOutputStream
◇ FilterInputStream、FilterOutputStream
◇ DataInputStream、DataOutputStream
◇ BufferedInputStream、BufferedOutputStream
2.字符流:(以16位的Unicode碼表示的字符)
從Reader和Writer派生出的一系列類:
◇ Reader、Writer
◇ InputStreamReader、OutputStreamWriter
◇ FileReader、FileWriter
◇ CharArrayReader、CharArrayWriter
◇ PipedReader、PipedWriter
◇ FilterReader、FilterWriter
◇ BufferedReader、BufferedWriter
◇ StringReader、StringWriter
3.對象流
◇ ObjectInputStream、ObjectOutputStream
4.其它:
◇ 文件處理:
File、RandomAccessFile;
◇ 接口
DataInput、DataOutput、ObjectInput、ObjectOutput;
InputStream
◇ 從流中讀取數據:
int read(
);?//讀取一個字節,返回值為所讀的字節 int
read( byte b[ ] );?//讀取多個字節,放置到字節數組b中,通常讀取的字節數量為b的長度
//返回值為實際讀取的字節的數量
int read( byte b[ ], int off, int len
);?//讀取len個字節,放置到以下標off開始字節數組b中
//返回值為實際讀取的字節的數量
int available( ); //返回值為流中尚未讀取的字節的數量
long skip( long n );?//讀指針跳過n個字節不讀,返回值為實際跳過的字節數量
◇ 關閉流:
close( );?//流操作完畢后必須關閉
◇ 使用輸入流中的標記:
void mark( int readlimit );?//記錄當前讀指針所在位置,讀指針讀出readlimit個字節后所標記的指針位置失效
void reset( );?//把讀指針重新指向用mark方法所記錄的位置
boolean markSupported( ); //當前的流是否支持讀指針的記錄功能
有關每個方法的使用,詳見java
API。
OutputStream
◇ 輸出數據:
void write( int b ); //往流中寫一個字節b
void write( byte b[ ] );?//往流中寫一個字節數組b
void write( byte b[ ], int off, int len
);?//字節數組b中從下標off開始,長度len的字節寫入流
◇ flush( ); //刷空輸出流,并輸出所有被緩存的字節
由于某些流支持緩存功能,該方法將把緩存中所有內容強制輸出到流中。
◇ 關閉流:
close( );?//流操作完畢后必須關閉
5.I/O中的異常:進行I/O操作時可能會產生I/O異常,屬于非運行時例外,應該在程序中處理。如:FileNotFoundException,
EOFException, IOException
(四)文件處理:
java.io包中有關文件處理的類有:File、FileInputStream、FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。
文件類(File):
◇ 文件或目錄的生成
public File(String path);
public File(String path,String name);//path是路徑名,name是文件名
public File(File dir,String name);//dir是路徑名,name是文件名
◇
文件名的處理
String getName( );?//得到一個文件的名稱(不包括路徑)
String getPath( );?//得到一個文件的路徑名
String getAbsolutePath( );//得到一個文件的絕對路徑名
String getParent( );?//得到一個文件的上一級目錄名
String renameTo(File newName);?//將當前文件名更名為給定文件的完整路徑(移動、復制粘貼)
◇
文件屬性測試
boolean exists( );?//測試當前File對象所指示的文件是否存在
boolean canWrite( );//測試當前文件是否可寫
boolean canRead( );//測試當前文件是否可讀
boolean isFile( );?//測試當前文件是否是文件(不是目錄)
boolean isDirectory( );?//測試當前文件是否是目錄(不是文件)
◇
普通文件信息和工具
long lastModified( );//得到文件最近一次修改的時間
long length( );?//得到文件的長度,以字節為單位
boolean delete( );?//是否刪除當前文件
◇
目錄操作
boolean mkdir( );?//根據當前對象生成一個由該對象指定的路徑
String list( );?//列出當前目錄下的文件
下面給出一個文件操作的實例:列出目錄D:\\ex\所有的.java文件
import
java.io.*;?//引入java.io包中所有的類
public class FileFilterTest{
public static void main(String args[]){
File dir=new File("d://ex");?//用File
對象表示一個目錄
Filter?filter=new?Filter("java");?//生成一個名為java的過濾器
System.out.println("list java files in directory "+dir);
String files[]=dir.list(filter);?//列出目錄dir下,文件后綴名為java的所有文件
for(int i=0;i
File f=new File(dir,files[i]);?//為目錄dir下的文件或目錄創建一個File對象
if(f.isFile())?//如果該對象為后綴為java的文件,則打印文件名
System.out.println("file "+f);
else
System.out.println("sub directory "+f
);?//如果是目錄則打印目錄名
}
}
}
class Filter implements FilenameFilter{
String extent;
Filter(String extent){
this.extent=extent;}
public boolean accept(File dir,String name){
return
name.endsWith("."+extent);?//返回文件的后綴名
}
}
【文件順序處理】類FileInputStream和FileOutputStream用來進行文件I/O處理,由它們所提供的方法可以打開本地主機上的文件,并進行順序的讀/寫。例如,下列的語句段是順序讀取文件名為text的文件里的內容,并顯示在控制臺上面,直到文件結束為止:FileInputStream
fis;
try{ fis = new FileInputStream( "text" );
System.out.print( "content of text is : ");
int b;
while( (b=fis.read())!=-1?)?//順序讀取文件text里的內容并賦值給整型變量b,直到文件結束 {
System.out.print( (char)b );
}
}catch( FileNotFoundException e ){
System.out.println( e );
}catch( IOException e ){
System.out.println( e );
}
【隨機訪問文件】
在java中,類RandomAccessFile提供了隨機訪問文件的方法。類RandomAccessFile的聲明為:
public class RandomAccessFile extends Object
implements?DataInput,
DataOutput接口DataInput中定義的方法:readBoolean(
)、readInt( )、readLine( )、readFully( )等
接口DataOutput中定義的方法:writeChar(
)、writeDouble( )、write( )等
類RandomAccessFile的方法:
◇ 構造方法: RandomAccessFile(String name,String
mode);?//name文件名,mode打開方式("r"只讀"rw"讀寫)
RandomAccessFile(File file,String
mode);?//file是文件對象
◇ 文件指針的操作
long getFilePointer( );?//用于得到當前的文件指針
void seek( long pos );?//用于移動文件指針到指定的位置
int skipBytes( int n );?//使文件指針向前移動指定的n個字節
(五)過濾流
過濾流在讀/寫數據的同時可以對數據進行處理,它提供了同步機制,使得某一時刻只有一個線程可以訪問一個I/O流,以防止多個線程同時對一個I/O流進行操作所帶來的意想不到的結果。
類FilterInputStream和FilterOutputStream分別作為所有過濾輸入流和輸出流的父類。
為了使用一個過濾流,必須首先把過濾流連接到某個輸入/出流上,通常通過在構造方法的參數中指定所要連接的輸入/出流來實現。
例如:
FilterInputStream( InputStream in );
FilterOutputStream( OutputStream out );
常見的過濾流:
◇
BufferedInputStream和BufferedOutputStream?緩沖流,用于提高輸入/輸出處理的效率
◇ DataInputStream 和
DataOutputStream?不僅能讀/寫數據流,而且能讀/寫數據基本類型。
◇
LineNumberInputStream?除了提供對輸入處理的支持外,還可以記錄當前的行號。
◇
PushbackInputStream?提供方法可以把剛讀過的字節退回到輸入流中,以便重新再讀一遍。
◇
PrintStream?打印流:把Java語言的內構類型以其字符表示形式送到相應的輸出流。
(六)字符流的處理java中提供了處理以16位的Unicode碼表示的字符流的類,即以Reader和Writer為基類派生出的一系列類。
1.Reader和Writer
Reader類是處理所有字符流輸入類的父類、Writer類是處理所有字符流輸出類的父類。
◇ 讀取字符(輸入流)
public int read() throws IOException; //讀取一個字符,返回值為讀取的字符
public int read(char cbuf[]) throws IOException;
//讀取一系列字符到數組cbuf[]中
public abstract int read(char cbuf[],int off,int len) throws
IOException; //必須由子類實現
◇
寫入字符(輸出流)
public void write(int c) throws IOException;
public void write(char cbuf[]) throws IOException;
public abstract void write(char cbuf[],int off,int len) throws
IOException;
public void write(String str) throws IOException;
public void write(String str,int off,int len) throws
IOException;
◇?flush(輸出流);刷空輸出流,并輸出(寫入)所有被緩存的字節。
◇ 標記流(輸入流)
public boolean markSupported();
public
void mark(int readAheadLimit) throws IOException;
public
void reset() throws IOException;
◇ 關閉流(輸入輸出流)
public abstract void close() throws IOException;
2.InputStreamReader 和
OutputStreamWriter:字節流和字符流的中介流◇
生成流對象 public InputStreamReader(InputStream
in);?//InputStreamReader可以把字節流in轉換成字符流
public InputStreamReader(InputStream in,String enc) throws
UnsupportedEncodingException;
public OutputStreamWriter(OutputStream out);
public OutputStreamWriter(OutputStream out,String enc) throws
UnsupportedEncodingException;
◇ 讀入和寫出字符
基本同Reader和Writer。
◇ 獲取當前編碼方式
public String?getEncoding();
◇ 關閉流
public void close() throws IOException;
3.BufferedReader
和 BufferedWriter:◇
生成流對象
public BufferedReader(Reader in);?//使用缺省的緩沖區大小
public BufferedReader(Reader in, int
sz);?//sz為緩沖區的大小
public BufferedWriter(Writer out);
public BufferedWriter(Writer out, int sz);
◇
讀入/寫出字符
除了Reader和Writer中提供的基本的讀寫方法外,增加對整行字符的處理 public String readLine() throws
IOException;?//讀一行字符
public void newLine() throws
IOException;?//寫一行字符
【例子】從鍵盤接收數據輸入:
import
java.io.*;
public class NumberInput{
public static void main(String args[]){
try{?InputStreamReader
ir;
BufferedReader in;
ir=new
InputStreamReader(System.in);?//從鍵盤接收了一個字符串的輸入,并創建了一個字符輸入流的對象
in=new BufferedReader(ir);
String s=in.readLine();//從輸入流in中讀入一行,并將讀取的值賦值給字符串變量s
System.out.println("Input value is: "+s);int
i = Integer.parseInt(s);//轉換成int型
i*=2;
System.out.println("Input value changed after doubled:
"+i);
}catch(IOException e)
{System.out.println(e);}
}
}
【注意】在讀取字符流時,如果不是來自于本地的,比如說來自于網絡上某處的與本地編碼方式不同的機器,那么我們在構造輸入流時就不能簡單地使用本地缺省的編碼方式,否則讀出的字符就不正確;為了正確地讀出異種機上的字符,我們應該使用下述方式構造輸入流對象:
ir = new
InputStreamReader(is, "8859_1");采用ISO
8859_1編碼方式,這是一種映射到ASCII碼的編碼方式,可以在不同平臺之間正確轉換字符。(七)對象的串行化(Serialization)我們把對象的這種能記錄自己的狀態以便將來再生的能力,叫做對象的持續性(persistence)。對象通過寫出描述自己狀態的數值來記錄自己,這個過程叫對象的串行化(Serialization)。
串行化目的:為java的運行環境提供一組特性,其主要任務是寫出對象實例變量的數值。
串行化方法:在java.io包中,只有實現了Serializable類的對象才可以被串行化。
串行化只能保存的元素:非靜態成員變量的值,不能保存變量任何修飾符。
transient關鍵字:暫時保存的對象
首先,定義一個可串行化對象
public class Student?implements
Serializable{
int id;?//學號
String name;?//姓名
int age;?//年齡
String department?//系別
public Student(int id,String name,int age,String
department){
this.id = id;
this.name = name;
this.age = age;
this.department = department;
}
}
其次,構造對象輸入輸出流:在ObjectInputStream中用readObject()方法直接讀取一個對象,ObjectOutputStream中用writeObject()方法直接將對象保存到輸出流中:
Student
stu=new Student(981036,"Liu Ming",18, "CSD");
FileOutputStream fo=new FileOutputStream("data.ser");//保存對象的狀態
ObjectOutputStream so=new ObjectOutputStream(fo);
try{so.writeObject(stu);
so.close();
}catch(IOException e )
{System.out.println(e);}
FileInputStream fi=new FileInputStream("data.ser");
ObjectInputStream si=new ObjectInputStream(fi);//恢復對象的狀態
try{stu=(Student)si.readObject();
si.close();
}catch(IOException e )
{System.out.println(e);}
在這個例子中,我們首先定義一個類Student,實現了
Serializable接口,然后通過對象輸出流的writeObject()方法將Student對象保存到文件data.ser中。之后,通過對象輸入流的readObject()方法從文件data.ser中讀出保存下來的Student對象。
(八)其他常用流:
1.管道流:PipedInputStream、PipedOutputStream
管道輸入流作為一個通信管道的接收端,管道輸出流作為發送端。在使用管道之前,管道輸出流和管道輸入流必須進行連接。下面有兩種連接的方法:構造方法中連接 PipedInputStream(PipedOutputStream src);
PipedOutputStream(PipedInputStream snk);
connect()方法進行連接
類PipedInputStream中定義為:
void connect(PipedOutputStream src);
類PipedOutputStream中定義為:
void connect(PipedInputStream snk);
2.內存的讀/寫:
ByteArrayInputStream和ByteArrayOutputStream?字節數組讀取寫入字節數據
StringBufferInputStream和StringBufferOutputStream字符串緩沖區中寫入讀取寫入字符數據
3.順序輸入流:
SequenceInputStream
把幾個輸入流順序連接起來。順序輸入流提供了把若干不同的流統一為同一個流的功能,使得程序變得更加簡潔。
總結
以上是生活随笔為你收集整理的java 运行异常处理_Java编程异常处理和I/O流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 渤海银行天津分行计算机笔试,关于渤海银行
- 下一篇: 调制方式相关总结