【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{
      public static void main( String args[ ] ){
       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)例外

 兩種處理例外的機制:

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

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

4.1.3 例外類的層次

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

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

  Error
 
  動態鏈接失敗,虛擬機錯誤等,通常Java程序不應該捕獲這類例外,也不會拋棄這種例外。

  Exception
  
  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( )用來跟蹤異常事件發生時執行堆棧的內容。例如:

  try{
    ......
   }catch( FileNotFoundException e ){
    System.out.println( e );
    System.out.println( "message: "+e.getMessage() );
    e.printStackTrace( System.out );
   }catch( IOException e ){
    System.out.println( 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( ); //列出當前目錄下的文件

 【例4-3】
  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<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 ){
   System.out.println( 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類中的方法。

 ◇ 構造方法:
  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個字節

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 幾種常見的過濾流

  ◇ BufferedInputStream和BufferedOutputStream
    緩衝流,用於提高輸入/輸出處理的效率。

  ◇ DataInputStream 和 DataOutputStream
    不僅能讀/寫數據流,而且能讀/寫各種的java語言的基本類型,如:boolean,int,float等。

  ◇ LineNumberInputStream
    除了提供對輸入處理的支持外,LineNumberInputStream可以記錄當前的行號。

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

  ◇ PrintStream
    打印流的作用是把Java語言的內構類型以其字符表示形式送到相應的輸出流。

4.7 字符流的處理

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

4.7.1 Reader和Writer

    這兩個類是抽象類,只是提供了一系列用於字符流處理的接口,不能生成這兩個類的實例,只能通過使用由它們派生出來的子類對象來處理字符流。

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

  ◇ 讀取字符 
  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處開始存放,返回值爲實際讀取的字符數量,該方法必須由子類實現*/

  ◇ 標記流
  public boolean markSupported(); //判斷當前流是否支持做標記
  public void mark(int readAheadLimit) throws IOException; 
   //給當前流作標記,最多支持readAheadLimit個字符的回溯。
  public void reset() throws IOException; //將當前流重置到做標記處

  ◇ 關閉流
  public abstract void close() throws IOException;

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

  ◇ 向輸出流寫入字符
  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個字符寫入輸出流

  ◇ flush( )
  刷空輸出流,並輸出所有被緩存的字節。

  ◇ 關閉流
  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的方法:

  ◇ 讀入和寫出字符
  基本同Reader和Writer。

  ◇ 獲取當前編碼方式
  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; //寫一行字符

【例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:\>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);
  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對象。

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碼爲處理單位的流。

發佈了11 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章