天天看點

JAVA教程 第四講 Java的例外處理和I/O流

4.1 什麼是例外

  例外就是在程式的運作過程中所發生的異常事件,它中斷指令的正常執行。Java中提供了一種獨特的處理例外的機制,通過例外來處理程式設計中出現的錯誤。

4.1.1 例外示例

【例4-1】

     import java.io.*;

     class ExceptionDemo1{

      public static void main( String args[ ] ){

       FileInputStream fis = new FileInputStream( "text" );

       int b;

       while( (b=fis.read())!=-1 ){

        System.out.print( b );

       }

       fis.close( );

      }

     }

    檢視編譯結果

【例4-2】

     class ExceptionDemo2{

       int a = 0;

       System.out.println( 5/a );

     }

    運作結果

C:\>javac ExceptionDemo2.java

C:\>java ExceptionDemo2

  java.lang.ArithmeticException: / by zero at

  ExceptionDemo2.main(ExceptionDemo2.java:4)

  因為除數不能為0,是以在程式運作的時候出現了除0溢出的異常事件。為什麼有的例外在編譯時出現,而有的例外是在運作時出現的?讓我們繼續學習java 的例外處理機制。

4.1.2 例外處理機制

  抛棄(throw)例外:

  在Java程式的執行過程中,如果出現了異常事件,就會生成一個例外對象。生成的例外對象将傳遞給Java運作時系統,這一例外的産生和送出過程稱為抛棄(throw)例外

 兩種處理例外的機制:

  <b>◇ 捕獲例外:</b>

  當Java運作時系統得到一個例外對象時,它将會沿着方法的調用棧逐層回溯,尋找處理這一例外的代碼。找到能夠處理這種類型的例外的方法後,運作時系統把目前例外對象交給這個方法進行處理,這一過程稱為捕獲(catch)例外。這是積極的例外處理機制。如果Java運作時系統找不到可以捕獲例外的方法,則運作時系統将終止,相應的Java程式也将退出。

  <b>◇ 聲明抛棄例外:</b>

  如果一個方法并不知道如何處理所出現的例外,則可在方法聲明時,聲明抛棄(throws)例外。這是一種消極的例外處理機制。

4.1.3 例外類的層次

  在jdk中,每個包中都定義了例外類,而所有的例外類都直接或間接地繼承于Throwable類。圖4-1為jdk中例外類的繼承關系。

  java中的例外類可分為兩大類:

  <b>Error</b>

 

  動态連結失敗,虛拟機錯誤等,通常Java程式不應該捕獲這類例外,也不會抛棄這種例外。

 <b> Exception</b>

  

  1)運作時例外:

  繼承于RuntimeException的類都屬于運作時例外,例如算術例外(除零錯)、數組下标越界例外等等。由于這些例外産生的位置是未知的,Java 編譯器允許程式員在程式中不對它們做出處理。

  2)非運作時例外:

  除了運作時例外之外的其他由Exception 繼承來的例外類都是非運作時的例外,例如FileNotFoundException(檔案未找到例外)。Java編譯器要求在程式中必須處理這種例外,捕獲例外或者聲明抛棄例外。

4.2 例外的處理

  java語言中有兩種例外處理機制:捕獲例外和聲明抛棄例外。下面我們做詳細介紹。

4.2.1 捕獲例外

  捕獲例外是通過try-catch-finally語句實作的。

  try{

  ......

   }catch( ExceptionName1 e ){

   ......

   }catch( ExceptionName2 e ){

   }

   }finally{

  }

  ◇ try

  捕獲例外的第一步是用try{…}標明捕獲例外的範圍,由try所限定的代碼塊中的語句在執行過程中可能會生成例外對象并抛棄。

  ◇ catch

  每個try代碼塊可以伴随一個或多個catch語句,用于處理try代碼塊中所生成的例外事件。catch語句隻需要一個形式參數指明它所能夠捕獲的例外類型,這個類必須是Throwable的子類,運作時系統通過參數值把被抛棄的例外對象傳遞給catch塊。

  在catch塊中是對例外對象進行處理的代碼,與通路其它對象一樣,可以通路一個例外對象的變量或調用它的方法。getMessage( )是類Throwable所提供的方法,用來得到有關異常事件的資訊,類Throwable還提供了方法printStackTrace( )用來跟蹤異常事件發生時執行堆棧的内容。例如:

    ......

   }catch( FileNotFoundException e ){

    System.out.println( e );

    System.out.println( "message: "+e.getMessage() );

    e.printStackTrace( System.out );

   }catch( IOException e ){

  catch 語句的順序:

  捕獲例外的順序和catch語句的順序有關,當捕獲到一個例外時,剩下的catch語句就不再進行比對。是以,在安排catch語句的順序時,首先應該捕獲最特殊的例外,然後再逐漸一般化。也就是一般先安排子類,再安排父類。

  ◇ finally

  捕獲例外的最後一步是通過finally語句為例外處理提供一個統一的出口,使得在控制流轉到程式的其它部分以前,能夠對程式的狀态作統一的管理。不論在try代碼塊中是否發生了異常事件,finally塊中的語句都會被執行。

4.2.2 聲明抛棄例外

 1.聲明抛棄例外

  如果在一個方法中生成了一個例外,但是這一方法并不确切地知道該如何對這一異常事件進行處理,這時,一個方法就應該聲明抛棄例外,使得例外對象可以從調用棧向後傳播,直到有合适的方法捕獲它為止。

  聲明抛棄例外是在一個方法聲明中的throws子句中指明的。例如:

  public int read () throws IOException{

        ......

  throws子句中同時可以指明多個例外,之間由逗号隔開。例如:

  public static void main(String args[]) throws

  IOException,IndexOutOfBoundsException {…}

 2.抛出例外

  抛出例外就是産生例外對象的過程,首先要生成例外對象,例外或者由虛拟機生成,或者由某些類的執行個體生成,也可以在程式中生成。在方法中,抛出例外對象是通過throw語句實作的。

  例如:

  IOException e=new IOException();

  throw e ;

  可以抛出的例外必須是Throwable或其子類的執行個體。下面的語句在編譯時将會産生文法錯誤:

  throw new String("want to throw");

4.3 自定義例外類的使用

  自定義例外類必須是Throwable的直接或間接子類。

  注意:一個方法所聲明抛棄的例外是作為這個方法與外界互動的一部分而存在的。是以,方法的調用者必須了解這些例外,并确定如何正确的處理他們。

4.4 I/O 流概述

  輸入/輸出處理是程式設計中非常重要的一部分,比如從鍵盤讀取資料、從檔案中讀取資料或向檔案中寫資料等等。

  Java把這些不同類型的輸入、輸出源抽象為流(stream),用統一接口來表示,進而使程式簡單明了。

  Jdk 提供了包java.io,其中包括一系列的類來實作輸入/輸出處理。下面我們對java.io包的内容進行概要的介紹。

4.4.1 I/O流的層次

  1.位元組流:

  從InputStream和OutputStream派生出來的一系列類。這類流以位元組(byte)為基本處理機關。

  ◇ InputStream、OutputStream

  ◇ FileInputStream、FileOutputStream

  ◇ PipedInputStream、PipedOutputStream

  ◇ ByteArrayInputStream、ByteArrayOutputStream

  ◇ FilterInputStream、FilterOutputStream

  ◇ DataInputStream、DataOutputStream

  ◇ BufferedInputStream、BufferedOutputStream

 2.字元流:

  從Reader和Writer派生出的一系列類,這類流以16位的Unicode碼表示的字元為基本處理機關。

  ◇ 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;

4.4.2 InputStream 和OutputStream

 1.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

                 //表示讀指針讀出readlimit個位元組後

                //所标記的指針位置才失效

  void reset( );     //把讀指針重新指向用mark方法所記錄的位置

  boolean markSupported( ); //目前的流是否支援讀指針的記錄功能

  有關每個方法的使用,詳見java API。

 2.OutputStream

  ◇ 輸出資料:

  void write( int b );   //往流中寫一個位元組b

  void write( byte b[ ] ); //往流中寫一個位元組數組b

  void write( byte b[ ], int off, int len ); //把位元組數組b中從

              //下标off開始,長度為len的位元組寫入流中

  ◇ flush( )       //刷空輸出流,并輸出所有被緩存的位元組

  由于某些流支援緩存功能,該方法将把緩存中所有内容強制輸出到流中。

   close( );       //流操作完畢後必須關閉

4.4.3 I/O中的例外

  進行I/O操作時可能會産生I/O例外,屬于非運作時例外,應該在程式中處理。如:FileNotFoundException, EOFException, IOException

4.5 檔案處理

  I/O進行中,最常見的是對檔案的操作,java.io包中有關檔案處理的類有:File、FileInputStream、FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。

4.5.1 檔案描述

  類File提供了一種與機器無關的方式來描述一個檔案對象的屬性。下面我們介紹類File中提供的各種方法。

 ◇ 檔案或目錄的生成

  public File(String path);/*如果path是實際存在的路徑,則該File對象

    /*表示的是目錄;如果path是檔案名,則該File對象表示的是檔案。*/

  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( ); //列出目前目錄下的檔案

 <b>【例4-3】</b>

  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&lt;files.length;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); //傳回檔案的字尾名

4.5.2 檔案的順序處理

  類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 ){

   }

4.5.3 随機通路檔案

  對于InputStream 和OutputStream 來說,它們的執行個體都是順序通路流,也就是說,隻能對檔案進行順序地讀/寫。随機通路檔案則允許對檔案内容進行随機讀/寫。在java中,類RandomAccessFile 提供了随機通路檔案的方法。類RandomAccessFile的聲明為:

public class RandomAccessFile extends Object implements DataInput, DataOutput

  接口DataInput 中定義的方法主要包括從流中讀取基本類型的資料、讀取一行資料、或者讀取指定長度的位元組數。如:readBoolean( )、readInt( )、readLine( )、readFully( ) 等。

  接口DataOutput 中定義的方法主要是向流中寫入基本類型的資料、或者寫入一定長度的位元組數組。如:writeChar( )、writeDouble( )、write( ) 等。 下面詳細介紹RandomAccessFile類中的方法。

 <b>◇ 構造方法:</b>

  RandomAccessFile(String name,String mode); //name是檔案名,mode

          //是打開方式,例如"r"表示隻讀,"rw"表示可讀寫,"

  RandomAccessFile(File file,String mode); //file是檔案對象

 <b>◇ 檔案指針的操作</b>

  long getFilePointer( ); //用于得到目前的檔案指針

  void seek( long pos ); //用于移動檔案指針到指定的位置

  int skipBytes( int n ); //使檔案指針向前移動指定的n個位元組

4.6 過濾流

  過濾流在讀/寫資料的同時可以對資料進行處理,它提供了同步機制,使得某一時刻隻有一個線程可以通路一個I/O流,以防止多個線程同時對一個I/O流進行操作所帶來的意想不到的結果。類FilterInputStream和FilterOutputStream分别作為所有過濾輸入流和輸出流的父類

  過濾流類層次:

          java.lang.Object

                |

                +----java.io.InputStream

                          |

                          +----java.io.FilterInputStream

  為了使用一個過濾流,必須首先把過濾流連接配接到某個輸入/出流上,通常通過在構造方法的參數中指定所要連接配接的輸入/出流來實作。例如:

  FilterInputStream( InputStream in );

  FilterOutputStream( OutputStream out );

4.6.1 幾種常見的過濾流

  <b>◇ BufferedInputStream和BufferedOutputStream</b>

    緩沖流,用于提高輸入/輸出處理的效率。

  <b>◇ DataInputStream 和 DataOutputStream</b>

    不僅能讀/寫資料流,而且能讀/寫各種的java語言的基本類型,如:boolean,int,float等。

  <b>◇ LineNumberInputStream</b>

    除了提供對輸入處理的支援外,LineNumberInputStream可以記錄目前的行号。

  <b>◇ PushbackInputStream</b>

    提供了一個方法可以把剛讀過的位元組退回到輸入流中,以便重新再讀一遍。

  <b>◇ PrintStream</b>

    列印流的作用是把Java語言的内構類型以其字元表示形式送到相應的輸出流。

4.7 字元流的處理

  java中提供了處理以16位的Unicode碼表示的字元流的類,即以Reader和Writer 為基類派生出的一系列類。

4.7.1 Reader和Writer

    這兩個類是抽象類,隻是提供了一系列用于字元流處理的接口,不能生成這兩個類的執行個體,隻能通過使用由它們派生出來的子類對象來處理字元流。

 1.Reader類是處理所有字元流輸入類的父類。

  <b>◇ 讀取字元 </b>

  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;

  /*讀取len個字元,從數組cbuf[]的下标off處開始存放,傳回值為實際讀取的字元數量,該方法必須由子類實作*/

  <b>◇ 标記流</b>

  public boolean markSupported(); //判斷目前流是否支援做标記

  public void mark(int readAheadLimit) throws IOException;

   //給目前流作标記,最多支援readAheadLimit個字元的回溯。

  public void reset() throws IOException; //将目前流重置到做标記處

  <b>◇ 關閉流</b>

  public abstract void close() throws IOException;

 2. Writer類是處理所有字元流輸出類的父類。

  <b>◇ 向輸出流寫入字元</b>

  public void write(int c) throws IOException;

  //将整型值c的低16位寫入輸出流

  public void write(char cbuf[]) throws IOException;

  //将字元數組cbuf[]寫入輸出流

  public abstract void write(char cbuf[],int off,int len) throws IOException;

  //将字元數組cbuf[]中的從索引為off的位置處開始的len個字元寫入輸出流

  public void write(String str) throws IOException;

  //将字元串str中的字元寫入輸出流

  public void write(String str,int off,int len) throws IOException;

  //将字元串str 中從索引off開始處的len個字元寫入輸出流

  <b>◇ flush( )</b>

  刷空輸出流,并輸出所有被緩存的位元組。

  public abstract void close() throws IOException;

4.7.2 InputStreamReader和OutputStreamWriter

  java.io包中用于處理字元流的最基本的類,用來在位元組流和字元流之間作為中介。

   ◇ 生成流對象

  public InputStreamReader(InputStream in);

  /*in是位元組流,而InputStreamReader是字元流,但是其來源是位元組流in,

  是以InputStreamReader就可以把位元組流in轉換成字元流處理。/*

  public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException;

  /*enc是編碼方式,就是從位元組流到字元流進行轉換時所采用的編碼方式,

   例如 ISO8859-1,UTF-8,UTF-16等等*/

  public OutputStreamWriter(OutputStream out);

  /*out是位元組流,而OutputStreamReader是字元流 */

  public OutputStreamWriter(OutputStream out,String enc) throws UnsupportedEncodingException; //enc是編碼方式

  InputStreamReader和OutputStreamWriter的方法:

  <b>◇ 讀入和寫出字元</b>

  基本同Reader和Writer。

  <b>◇ 擷取目前編碼方式</b>

  public String getEncoding();

  public void close() throws IOException;

4.7.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; //寫一行字元

<b></b>

【例4-4】

  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);}

D:\&gt;java NumberInput

123

Input value is 123

Input value changed after doubled: 246

  注意:在讀取字元流時,如果不是來自于本地的,比如說來自于網絡上某處的與本地編碼方式不同的機器,那麼我們在構造輸入流時就不能簡單地使用本地預設的編碼方式,否則讀出的字元就不正确;為了正确地讀出異種機上的字元,我們應該使用下述方式構造輸入流對象:

    ir = new InputStreamReader(is, "8859_1");

  采用ISO 8859_1編碼方式,這是一種映射到ASCII碼的編碼方式,可以在不同平台之間正确轉換字元。

4.8 對象的串行化(Serialization)

4.8.1 串行化的定義

    1. 什麼是串行化

  對象的壽命通常随着生成該對象的程式的終止而終止。有時候,可能需要将對象的狀态儲存下來,在需要時再将對象恢複。我們把對象的這種能記錄自己的狀态以便将來再生的能力,叫做對象的持續性(persistence)。對象通過寫出描述自己狀态的數值來記錄自己,這個過程叫對象的串行化(Serialization)。

   2. 串行化的目的

  串行化的目的是為java的運作環境提供一組特性,其主要任務是寫出對象執行個體變量的數值。

4.8.2 串行化方法

  在java.io包中,接口Serializable用來作為實作對象串行化的工具,隻有實作了Serializable的類的對象才可以被串行化。

 1. 定義一個可串行化對象

  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;

 2. 構造對象的輸入/輸出流

  要串行化一個對象,必須與一定的對象輸入/輸出流聯系起來,通過對象輸出流将對象狀态儲存下來,再通過對象輸入流将對象狀态恢複。

  java.io包中,提供了ObjectInputStream和ObjectOutputStream将資料流功能擴充至可讀寫對象。在ObjectInputStream中用readObject()方法可以直接讀取一個對象,ObjectOutputStream中用writeObject()方法可以直接将對象儲存到輸出流中。

  Student stu=new Student(981036,"Liu Ming",18, "CSD");

  FileOutputStream fo=new FileOutputStream("data.ser");

  //儲存對象的狀态

  ObjectOutputStream so=new ObjectOutputStream(fo);

    so.writeObject(stu);

    so.close();

    }catch(IOException e )

      {System.out.println(e);}

  FileInputStream fi=new FileInputStream("data.ser");

  ObjectInputStream si=new ObjectInputStream(fi);

  //恢複對象的狀态

    stu=(Student)si.readObject();

    si.close();

  {System.out.println(e);}

  在這個例子中,我們首先定義一個類Student,實作了 Serializable接口,然後通過對象輸出流的writeObject()方法将Student對象儲存到檔案data.ser中。之後,通過對象輸入流的readObject()方法從檔案data.ser中讀出儲存下來的Student對象。

4.8.3 串行化的注意事項

 1.串行化能儲存的元素

  隻能儲存對象的非靜态成員變量,不能儲存任何的成員方法和靜态的成員變量,而且串行化儲存的隻是變量的值,對于變量的任何修飾符,都不能儲存。

 2.transient關鍵字

  對于某些類型的對象,其狀态是瞬時的,這樣的對象是無法儲存其狀态的,例如一個Thread對象,或一個FileInputStream對象,對于這些字段,我們必須用transient關鍵字标明

 3. 定制串行化

  預設的串行化機制,對象串行化首先寫入類資料和類字段的資訊,然後按照名稱的上升排列順序寫入其數值。如果想自己明确地控制這些數值的寫入順序和寫入種類,必須定義自己的讀取資料流的方式。就是在類的定義中重寫writeObject()和readObject()方法。

  例如可在4.8.2的例子中,加入重寫的writeObject()和readObject()方法,對Student 類定制其串行化。

  private void writeObject(ObjectOutputStream out)throws IOException

  {

    out.writeInt(id);

    out.writeInt(age);

    out.writeUTF(name);

    out.writeUTF(department);

  private void readObject(ObjectInputStream in)throws IOException

    id=in.readInt();

    age=in.readInt();

    name=in.readUTF();

    department=in.readUTF();

4.9 其它常用的流

4.9.1 管道流

  管道用來把一個程式、線程或代碼塊的輸出連接配接到另一個程式、線程或代碼塊的輸入 。

  管道輸入流作為一個通信管道的接收端,管道輸出流作為發送端。在使用管道之前,管道輸出流和管道輸入流必須進行連接配接。下面有兩種連接配接的方法:

 1. 構造方法中連接配接

  PipedInputStream(PipedOutputStream src);

  PipedOutputStream(PipedInputStream snk);

 2. connect()方法進行連接配接

  類PipedInputStream中定義為:

  void connect(PipedOutputStream src);

  類PipedOutputStream中定義為:

  void connect(PipedInputStream snk);

4.9.2 記憶體的讀/寫

 1. ByteArrayInputStream和ByteArrayOutputStream

  ByteArrayInputStream //從位元組數組中讀取以位元組為機關的資料

  ByteArrayOutputStream //向位元組數組中寫入以位元組為機關的資料

 2. StringBufferInputStream和StringBufferOutputStream

  StringBufferInputStream

  //從字元串緩沖區StringBuffer中讀取以字元為機關的資料

  StringBufferOutputStream

  //向字元串緩沖區StringBuffer中寫入以字元為機關的資料

4.9.3 順序輸入流

  SequenceInputStream 把幾個輸入流順序連接配接起來。順序輸入流提供了把若幹不同的流統一為同一個流的功能,使得程式變得更加簡潔。

【本講小結】

  例外處理是java語言中一個獨特之處,主要使用捕獲例外和聲明抛棄例外兩種方法來處理程式中可能出現例外的語句塊,其中捕獲例外的方法是一種積極地處理例外的方法,而聲明抛棄例外是一種消極的處理例外的方法。

  Java中的輸入/輸出處理是通過使用流技術,用統一的接口表示而實作的。輸入/輸出流中,最常見的是對檔案的處理。Java語言中提供專門處理檔案和目錄的類,例如:java.io.File,java.io.FileInputStream,java.io.FileOutputStream,java.io.RandomAccessFile和接口java.io.FilenameFilter。輸入/輸出流根據處理的内容,分為字元流和位元組流兩種,其中位元組流是以byte為基本處理機關的流;而字元流是以16位的Unicode碼為處理機關的流。