JAVA-IO詳解 



一. Input和Output

  1. stream代表的是任何有能力產出數據的數據源,或是任何有能力接收數據的接收源。在Java的IO中,所有的stream(包括Input和Out stream)都包括兩種類型:



 1.1 以字節為導向的stream

  以字節為導向的stream,表示以字節為單位從stream中讀取或往stream中寫入信息。以字節為導向的stream  包括下面幾種類型:
  1) input stream:
  1) ByteArrayInputStream:把內存中的一個緩沖區作為InputStream使用
  2) StringBufferInputStream:把一個String對象作為InputStream
  3) FileInputStream:把一個文件作為InputStream,實現對文件的讀取操作
  4) PipedInputStream:實現了pipe的概念,主要在線程中使用
  5) SequenceInputStream:把多個InputStream合并為一個InputStream
  2) Out stream
  1) ByteArrayOutputStream:把信息存入內存中的一個緩沖區中
  2) FileOutputStream:把信息存入文件中
  3) PipedOutputStream:實現了pipe的概念,主要在線程中使用
  4) SequenceOutputStream:把多個OutStream合并為一個OutStream

  1.2 以Unicode字符為導向的stream

  以Unicode字符為導向的stream,表示以Unicode字符為單位從stream中讀取或往stream中寫入信息。以   Unicode字符為導向的stream包括下面幾種類型:
 1) Input Stream
  1) CharArrayReader:與ByteArrayInputStream對應
  2) StringReader:與StringBufferInputStream對應
  3) FileReader:與FileInputStream對應
  4) PipedReader:與PipedInputStream對應
  2) Out Stream
  1) CharArrayWrite:與ByteArrayOutputStream對應
  2) StringWrite:無與之對應的以字節為導向的stream
  3) FileWrite:與FileOutputStream對應
  4) PipedWrite:與PipedOutputStream對應

   以字符為導向的stream基本上對有與之相對應的以字節為導向的stream。兩個對應類實現的功能相同,字是在操作時的導向不同。如 CharArrayReader:和ByteArrayInputStream的作用都是把內存中的一個緩沖區作為InputStream使用,所不同的 是前者每次從內存中讀取一個字節的信息,而后者每次從內存中讀取一個字符。

  1.3 兩種不現導向的stream之間的轉換

  InputStreamReader和OutputStreamReader:把一個以字節為導向的stream轉換成一個以字符為導向的stream。

  2. stream添加屬性

  2.1 “為stream添加屬性”的作用

  運用上面介紹的Java中操作IO的API,我們就可完成我們想完成的任何操作了。但通過FilterInputStream和FilterOutStream的子類,我們可以為stream添加屬性。下面以一個例子來說明這種功能的作用。
如果我們要往一個文件中寫入數據,我們可以這樣操作:

 
 FileOutStream fs = new FileOutStream(“test.txt”);
 



   然后就可以通過產生的fs對象調用write()函數來往test.txt文件中寫入數據了。但是,如果我們想實現“先把要寫入文件的數據先緩存到內存 中,再把緩存中的數據寫入文件中”的功能時,上面的API就沒有一個能滿足我們的需求了。但是通過FilterInputStream和 FilterOutStream的子類,為FileOutStream添加我們所需要的功能。
  2.2 FilterInputStream的各種類型





***

*** 


  2.2.1 用于封裝以字節為導向的InputStream
 
  1) DataInputStream:從stream中讀取基本類型(int、char等)數據。
  2) BufferedInputStream:使用緩沖區
  3) LineNumberInputStream:會記錄input stream內的行數,然后可以調用getLineNumber()和setLineNumber(int)
  4) PushbackInputStream:很少用到,一般用于編譯器開發

  2.2.2 用于封裝以字符為導向的InputStream

  1) 沒有與DataInputStream對應的類。除非在要使用readLine()時改用BufferedReader,否則使用DataInputStream



作者: 222.67.6.*  2007-2-7 07:49   回復此發言  


2 java io

  2) BufferedReader:與BufferedInputStream對應
  3) LineNumberReader:與LineNumberInputStream對應
  4) PushBackReader:與PushbackInputStream對應

  2.3 FilterOutStream的各種類型

  2.2.3 用于封裝以字節為導向的OutputStream

  1) DataIOutStream:往stream中輸出基本類型(int、char等)數據。
  2) BufferedOutStream:使用緩沖區
  3) PrintStream:產生格式化輸出
  2.2.4 用于封裝以字符為導向的OutputStream

  1) BufferedWrite:與對應
  2) PrintWrite:與對應
  3. RandomAccessFile
  1) 可通過RandomAccessFile對象完成對文件的讀寫操作
  2) 在產生一個對象時,可指明要打開的文件的性質:r,只讀;w,只寫;rw可讀寫
  3) 可以直接跳到文件中指定的位置


 
什么是IO 
--------------------------------------------------------------------------------
IO(Input/Output)是計算機輸出/輸出的接口。Java的核心庫java.io提供了全面的IO接口,包括:文件讀寫,標準設備輸出等 等。Java中IO是以流為基礎進行輸入輸出的,所有數據被串行化寫入輸出流,或者從輸入流讀入。此外,Java也對塊傳輸提供支持,在核心庫 java.nio中采用的便是塊IO。關于NIO我們在后面還有專門的討論。
  流IO的好處是簡單易用,缺點是效率較低。塊IO效率很高,但編程比較復雜。

Java IO模型 
--------------------------------------------------------------------------------
Java的IO模型設計非常優秀,它使用Decorator模式,按功能劃分Stream,您可以動態裝配這些Stream,以便獲得您需要的功能。例 如,您需要一個具有緩沖的文件輸入流,則應當組合使用FileInputStream和BufferedInputStream。
  Java的IO體系分Input/Output和Reader/Writer兩類,區別在于Reader/Writer在讀寫文本時能自動轉換內碼。基本上,所有的IO類都是配對的,即有XxxInput就有一個對應的XxxOutput。

Java IO教程 
--------------------------------------------------------------------------------
如果您對Decorator模式非常了解,就能輕易地看出Java的IO類結構:根接口是InputStream/OutputStream,充當數據 源的IO類有FileInputStream/FileOutputStream, ByteArrayInputStream/ByteArrayOutputStream等,充當裝飾功能的IO類有 BufferedInputStream/BufferedOutputStream, DataInputStream/DataOutputStream等,它們都是繼承裝飾接口 FilterInputStream/FilterOutputStream。使用IO時,首先創建一個數據源IO,然后根據需要的功能創建裝飾類IO, 其構造函數的參數為已創建的數據源IO。我們以創建一個具有緩沖的文件輸入流為例,假定需要從磁盤讀取文件“C:\log.txt”:
// 創建一個FileInputStream:
FileInputStream fileInput = new FileInputStream("C:\\log.txt"); 
// 創建一個BufferedInputStream:
BufferedInputStream bufferedInput = new BufferedInputStream(fileInput); 
// 現在得到的bufferedInput即是具有緩沖的文件輸入流 
  或者進一步簡寫如下:
InputStream input = new BufferedInputStream(
new FileInputStream("C:\\log.txt"));
// 現在得到的input即是具有緩沖的文件輸入流 
  在您對Java的IO有了總體了解后,我們推薦您看看教程Introduction to Java I/O和I/O: Reading and Writing。




作者: 222.67.6.*  2007-2-7 07:49   回復此發言  


3 回復:java io

java io 總結

java中的io系統總結.

java中的io中的(input/output)stream無非就是包括基于字符的stream、基于字節的stream和把字節導向的stream轉換
字符為導向的stream的stream。(很難理解么?)
以字節為導向的stream------InputStream/OutputStream
InputStream 和 OutputStream是兩個abstact類,對于字節為導向的stream都擴展這兩個雞肋(基類^_^);
--InputStream
ByteArrayInputStream -- 把內存中的一個緩沖區作為InputStream使用.

construct---ByteArrayInputStream(byte[])創建一個新字節數組輸入流,它從指定字節數組中讀取數據。
---ByteArrayInputStream(byte[], int, int) 創建一個新字節數組輸入流,它從指定字節數組中讀取數據。
---mark::該字節數組未被復制。

StringBufferInputStream -- 把一個String對象作為InputStream .
注釋:不推薦使用 StringBufferInputStream 方法。 此類不能將字符正確的轉換為字節。
同 JDK 1.1 版中的類似,從一個串創建一個流的最佳方法是采用 StringReader 類。 

construct---StringBufferInputStream(String) 據指定串創建一個讀取數據的輸入流串。

FileInputStream -- 把一個文件作為InputStream,實現對文件的讀取操作 

construct---FileInputStream(File) 創建一個輸入文件流,從指定的 File 對象讀取數據。
---FileInputStream(FileDescriptor) 創建一個輸入文件流,從指定的文件描述器讀取數據。
---FileInputStream(String) 創建一個輸入文件流,從指定名稱的文件讀取數據。

method ---- read() 從當前輸入流中讀取一字節數據。 
read(byte[]) 將當前輸入流中 b.length 個字節數據讀到一個字節數組中。 
read(byte[], int, int) 將輸入流中 len 個字節數據讀入一個字節數組中。

PipedInputStream:實現了pipe的概念,主要在線程中使用. 管道輸入流是指一個通訊管道的接收端。
一個線程通過管道輸出流發送數據,而另一個線程通過管道輸入流讀取數據,
這樣可實現兩個線程間的通訊。

PipedInputStream() 創建一個管道輸入流,它還未與一個管道輸出流連接。 
PipedInputStream(PipedOutputStream) 創建一個管道輸入流, 它已連接到一個管道輸出流。 

SequenceInputStream:把多個InputStream合并為一個InputStream .“序列輸入流”類允許應用程序把幾個輸入流連續地合并起來,
并且使它們像單個輸入流一樣出現。每個輸入流依次被讀取,直到到達該流的末尾。
然后“序列輸入流”類關閉這個流并自動地切換到下一個輸入流。 
SequenceInputStream(Enumeration) 創建一個新的序列輸入流,并用指定的輸入流的枚舉值初始化它。 
SequenceInputStream(InputStream, InputStream) 創建一個新的序列輸入流,初始化為首先 讀輸入流 s1, 然后讀輸入流 s2。

--OutputSteam

ByteArrayOutputStream:把信息存入內存中的一個緩沖區中.該類實現一個以字節數組形式寫入數據的輸出流。
當數據寫入緩沖區時,它自動擴大。用 toByteArray() 和 toString() 能檢索數據。 

construct --- ByteArrayOutputStream() 創建一個新的字節數組輸出流。
--- ByteArrayOutputStream() 創建一個新的字節數組輸出流。 
--- ByteArrayOutputStream(int) 創建一個新的字節數組輸出流,并帶有指定大小字節的緩沖區容量。 
toString(String) 根據指定字符編碼將緩沖區內容轉換為字符串,并將字節轉換為字符。 
write(byte[], int, int) 將指定字節數組中從偏移量 off 開始的 len 個字節寫入該字節數組輸出流。 
write(int) 將指定字節寫入該字節數組輸出流。 
writeTo(OutputStream) 用 out.write(buf, 0, count) 調用輸出流的寫方法將該字節數組輸出流的全部內容寫入指定的輸出流參數。 

FileOutputStream:文件輸出流是向 File 或 FileDescriptor 輸出數據的一個輸出流。



作者: 222.67.6.*  2007-2-8 07:40   回復此發言  


4 回復:java io


FileOutputStream(File) 創建一個文件輸出流,向指定的 File 對象輸出數據。 
FileOutputStream(FileDescriptor) 創建一個文件輸出流,向指定的文件描述器輸出數據。 
FileOutputStream(String) 創建一個文件輸出流,向指定名稱的文件輸出數據。 
FileOutputStream(String, boolean) 用指定系統的文件名,創建一個輸出文件。

PipedOutputStream:管道輸出流是指一個通訊管道的發送端。 一個線程通過管道輸出流發送數據,
而另一個線程通過管道輸入流讀取數據,這樣可實現兩個線程間的通訊。

PipedOutputStream() 創建一個管道輸出流,它還未與一個管道輸入流連接。 
PipedOutputStream(PipedInputStream) 創建一個管道輸出流,它已連接到一個管道輸入流。


以字符為導向的stream Reader/Writer

以Unicode字符為導向的stream,表示以Unicode字符為單位從stream中讀取或往stream 中寫入信息。
Reader/Writer 為abstact類
以Unicode字符為導向的stream包括下面幾種類型: 

-- Reader

1) CharArrayReader:與ByteArrayInputStream對應 
CharArrayReader(char[]) 用指定字符數組創建一個 CharArrayReader。
CharArrayReader(char[], int, int) 用指定字符數組創建一個 CharArrayReader。

2) StringReader:與StringBufferInputStream對應 
StringReader(String) 創建一新的串讀取者。
3) FileReader:與FileInputStream對應 

4) PipedReader:與PipedInputStream對應 

-- Writer

1) CharArrayWrite:與ByteArrayOutputStream對應 
2) StringWrite:無與之對應的以字節為導向的stream 
3) FileWrite:與FileOutputStream對應 
4) PipedWrite:與PipedOutputStream對應 

兩種不現導向的stream之間的轉換
InputStreamReader和OutputStreamReader:把一個以字節為導向的stream轉換成一個以字符為導向的stream。
一個 InputStreamReader 類是從字節流到字符流的橋梁:它讀入字節,并根據指定的編碼方式,將之轉換為字符流。
使用的編碼方式可能由名稱指定,或平臺可接受的缺省編碼方式。

InputStreamReader 的 read() 方法之一的每次調用,可能促使從基本字節輸入流中讀取一個或多個字節。
為了達到更高效率,考慮用 BufferedReader 封裝 InputStreamReader,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

InputStreamReader(InputStream) 用缺省的字符編碼方式,創建一個 InputStreamReader。 
InputStreamReader(InputStream, String) 用已命名的字符編碼方式,創建一個 InputStreamReader。

OutputStreamWriter 將多個字符寫入到一個輸出流,根據指定的字符編碼將多個字符轉換為字節。 
每個 OutputStreamWriter 合并它自己的 CharToByteConverter, 因而是從字符流到字節流的橋梁。

FilterInputStream、RandomAccessFile 見例子。
ObjectInputStream 、 ObjectOutputStream見另外blog。


Java IO的一般使用原則:

一、按數據來源(去向)分類:
1、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter
2、是byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、是Char[]: CharArrayReader, CharArrayWriter
4、是String: StringBufferInputStream, StringReader, StringWriter
5、網絡數據流:InputStream, OutputStream, Reader, Writer

二、按是否格式化輸出分:
1、要格式化輸出:PrintStream, PrintWriter

三、按是否要緩沖分:
1、要緩沖:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter

四、按數據格式分:
1、二進制格式(只要不能確定是純文本的): InputStream, OutputStream及其所有帶Stream結束的子類
2、純文本格式(含純英文與漢字或其他編碼方式);Reader, Writer及其所有帶Reader, Writer的子類

五、按輸入輸出分:
1、輸入:Reader, InputStream類型的子類
2、輸出:Writer, OutputStream類型的子類

六、特殊需要:
1、從Stream到Reader,Writer的轉換類:InputStreamReader, OutputStreamWriter
2、對象輸入輸出:ObjectInputStream, ObjectOutputStream
3、進程間通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4、合并輸入:SequenceInputStream
5、更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

決定使用哪個類以及它的構造進程的一般準則如下(不考慮特殊需要):
首先,考慮最原始的數據格式是什么: 原則四
第二,是輸入還是輸出:原則五
第三,是否需要轉換流:原則六第1點
第四,數據來源(去向)是什么:原則一
第五,是否要緩沖:原則三 (特別注明:一定要注意的是readLine()是否有定義,有什么比read, write更特殊的輸入或輸出方法)
第六,是否要格式化輸出:原則二



作者: 222.67.6.*  2007-2-8 07:40   回復此發言  


5 回復:java io

使用Java 輸出/輸出流讀寫數據 

Java  輸入/輸出(I/O)機制提供了一套簡單的,標準化的API以便從不同的數據源讀取和寫入字符和字節數據。在“面向對象編程: Java collection更有效管理elements”一文中,我們討論了Java 集合類架構中的類和功能并介紹了它的排序功能。在本文中,我們 將學習Java 平臺提供的這些I/O類,接口和操作。讓我們先從了解Java 數據流開始。 
數據流
 
Java所有的I/O機制都是基于數據流的,這些數據流表示了字符或者字節數據的流動序列。Java的I/O流提供了讀寫數據的標準方法。任何Java中表示數據源的對象都會提供以數據流的方式讀寫它的數據的方法。 

Java.io是大多數面向數據流的輸入/輸出類的主要軟件包。這個軟件包包含了兩個抽象類,InputStream和OutputStream。所有其它面象數據流的輸入/輸出類都要擴展這兩個基類。 

java.io 軟件包提供了一些類和接口,它們在由InputStream和OuputStream類提供的讀寫操作的頂端定義了一些有用的抽象。例如, ObjectInputStream類提供了讓你把輸入/輸出流中的數據當成對象來讀取的方法,而ObjectOutputStream類提供了讓你能夠 把Java對象寫入數據流中的方法。 

優化讀寫過程
JDK 1.1 增加了一套讀寫類,它們提供了比現有數據流類更有用的 抽象和更好的輸入/輸出性能。例如,BufferedReader和BufferedWriter 類被用來從基于字符的輸入和輸出流中讀取和寫入文本。 BufferdReader 類緩存字符以更高效的讀取字符串,數組和文本行。BufferedWriter類緩存字符以更高效的寫入字符串,數組和文本 行。BufferedReader和BufferedWriter 類可以按需求進行設置。 

Java輸入/輸出架構提供的讀取器和 寫入器類包括 LineNumberReader 類,CharArrayReader類,FileReader類,FilterReader類, PushbackReader類,PipedReader類,StringReader類以及其它一些類。這些類是在InputStream和 OuputStream類頂部的包裹類因此提供了與InputStream和OuputStream類相似的方法。但是,這些類為讀寫特定的對象,比方文 件,字符數組和字符串等等提供了更高效而有用的抽象。 

讀取數據
當你從一個相應的數據源對象里提取輸入流或者是創建一個讀取器對象的時候就會自動打開一個輸入流。例如,要為一個文件打開輸入流,我們只需要以下面的方式把文件名傳遞給Java.io.FileReader對象的構造函數: 

java.io.FileReader fileReader = new java.io.FileReader("/home/me/myfile.txt"); 

要按順序讀取FileReader底層的輸入流中的一個字節數據,只需要使用不帶參數的read方法。表A中的代碼段從一個文件讀取文本數據,一次一個字符,然后把它寫入System.out里。 

要從輸入流讀取指定數目的字節數據到char數組里,只需要使用帶一個char[]參數的read方法。數組的長度被用來確定應該讀取的字符的個數。表B演示了這個技術。 

要關閉一個輸入流以及這個流使用的所有系統資源,你只需要以下面的方式調用close方法: 

fileReader.close(); 

寫入數據
象一個輸入流一樣,輸出流通常在你從相應的數據源提取它或者是在你創建一個寫入對象的時候被自動的打開。例如,要為一個文件打開輸出流,我們把文件的名字傳遞給java.io.FileWriter對象的構造函數,如下所示: 

java.io.FileWriter fileWriter = new 
java.io.FileWriter("/home/me/out.txt"); 

要將一個特定的字符寫入到輸出流中,可以使用帶一個int參數的write方法,int參數代表要定入的字符。 

int aChar = (int)'X'; 
fileWriter.write(aChar); 

要在輸出流給定的偏移地址寫入一個char數組中特定數目的字符,你可以使用帶一個char[]參數,一個int 偏移量參數和一個int長度參數的write方法,如下面的例子所示: 

fileWriter.write(buffer, 0, byteCount); 

要關閉一個輸出流并釋放所有與之相關的系統資源,可以使用close方法,就象這樣: 

fileWriter.close(); 

要強迫寫出一個輸出流中的所有數據,可以使用下面的flush方法: 

fileWriter.flush(); 

把它們全部綜合起來
我們可以使用我們學習過的這些函數從一個文件中讀取數據并同時寫到另一個文件中去,如表C所示。 

總結
Java的輸入/輸出機制為從不同的數據源讀取和寫入字符增加了一套簡單而標準化的API。你對一種數據源使用Java流的經驗能夠讓你容易的使用其它由Java提供的數據源類型。 

在我們下一篇文章中,我們將會開始學習Java平臺的聯網和遠程通訊架構。我們將會把我們對Java流的討論擴展到這些環境并演示如何打開遠程數據源,并象操作本地數據源,比方文件一樣,寫入數據和讀取數據



作者: 222.67.6.*  2007-2-8 07:42   回復此發言  


6 回復:java io

字符流的處理

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

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

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; 

 

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

    運行結果 


D:\>java NumberInput
123
Input value is 123
Input value changed after doubled: 246 


 注意:在讀取字符流時,如果不是來自于本地的,比如說來自于網絡上某處的與本地編碼方式不同的機器,那么我們在構造輸入流時就不能簡單地使用本地缺省的編碼方式,否則讀出的字符就不正確;為了正確地讀出異種機上的字符,我們應該使用下述方式構造輸入流對象:
  
    ir = new InputStreamReader(is, "8859_1");

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



作者: 222.67.6.*  2007-2-8 07:44   回復此發言  


7 回復:java io

JAVA IO

流一般分為輸入流(Input Stream)和輸出流(Output Stream)兩類,但這種劃分并不是絕對的。比如一個文件,當向其中寫數據時,它就是一個輸出流;當從其中讀取數據時,它就是一個輸入流.

字節流:
  從InputStream和OutputStream派生出來的一系列類。這類流以字節(byte)為基本處理單位。

字符流:
  從Reader和Writer派生出的一系列類,這類流以16位的Unicode碼表示的字符為基本處理單位.

Reader類和Writer類 
前 面說過,在JDK1.1之前,java.io包中的流只有普通的字節流(以byte為基本處理單位的流),這種流對于以16位的Unicode碼表示的字 符流處理很不方便。從JDK1.1開始, java.io包中加入了專門用于字符流處理的類,它們是以Reader和Writer為基礎派生的一系列類
同類InputStream和OutputStream一樣,Reader和Writer也是抽象類,只提供了一系列用于字符流處理的接口。它們的方法與類InputStream和OutputStream類似,只不過其中的參數換成字符或字符數組



作者: 222.67.6.*  2007-2-8 07:44   回復此發言  


8 回復:java io

java class diagram

貼子相關圖片:

作者: 222.67.6.*  2007-2-8 07:54   回復此發言  


9 回復:java io

java將讀取數據對象成為輸入流,能向其寫入的對象叫輸出流。結構圖如下:輸入流:

貼子相關圖片:

作者: 222.67.6.*  2007-2-8 07:55   回復此發言  


10 回復:java io

Reader的體系結構

貼子相關圖片:

作者: 222.67.6.*  2007-2-8 07:56   回復此發言  


11 回復:java io

Writer類體系結構

貼子相關圖片:

作者: 222.67.6.*  2007-2-8 07:56   回復此發言  


12 回復:java io

Introducing I/O
Input and output, I/O for short, are fundamental to any computer operating system or programming language. Only theorists find it interesting to write programs that don't require input or produce output. At the same time, I/O hardly qualifies as one of the more "thrilling" topics in computer science. It's something in the background, something you use every daybut for most developers, it's not a topic with much sex appeal.

But in fact, there are plenty of reasons Java programmers should find I/O interesting. Java includes a particularly rich set of I/O classes in the core API, mostly in the java.io and java.nio packages. These packages support several different styles of I/O. One distinction is between byte-oriented I/O, which is handled by input and output streams, and character-I/O, which is handled by readers and writers. Another distinction is between the old-style stream-based I/O and the new-style channel- and buffer-based I/O. These all have their place and are appropriate for different needs and use cases. None of them should be ignored.

Java's I/O libraries are designed in an abstract way that enables you to read from external data sources and write to external targets, regardless of the kind of thing you're writing to or reading from. You use the same methods to read from a file that you do to read from the console or from a network connection. You use the same methods to write to a file that you do to write to a byte array or a serial port device.

Reading and writing without caring where your data is coming from or where it's going is a very powerful abstraction. Among other things, this enables you to define I/O streams that automatically compress, encrypt, and filter from one data format to another. Once you have these tools, programs can send encrypted data or write zip files with almost no knowledge of what they're doing. Cryptography or compression can be isolated in a few lines of code that say, "Oh yes, make this a compressed, encrypted output stream."

In this book, I'll take a thorough look at all parts of Java's I/O facilities. This includes all the different kinds of streams you can use and the channels and buffers that offer high-performance, high-throughput, nonblocking operations on servers. We're also going to investigate Java's support for Unicode. We'll look at Java's powerful facilities for formatting I/O. Finally, we'll look at the various APIs Java provides for low-level I/O through various devices including serial ports, parallel ports, USB, Bluetooth, and other hardware you'll find in devices that don't necessarily look like a traditional desktop computer or server.

I won't go so far as to say, "If you've always found I/O boring, this is the book for you!" I will say that if you do find I/O uninteresting, you probably don't know as much about it as you should. I/O is the means for communication between software and the outside world. Java provides a powerful and flexible set of tools for doing this crucial part of the job. Having said that, let's start with the basics.



作者: 222.67.6.*  2007-2-8 07:57   回復此發言  


13 回復:java io

java io 簡介


stream代表的是任何有能力產出數據的數據源,或是任何有能力接收數據的接收源。在Java的IO中,所有的stream(包括Inputstream和Out stream)都包括兩種類型:
(1)字節流
 表示以字節為單位從stream中讀取或往stream中寫入信息,即io包中的inputstream類和outputstream類的派生類。通常用來讀取二進制數據,如圖象和聲音。

(2)字符流 

以Unicode字符為導向的stream,表示以Unicode字符為單位從stream中讀取或往stream中寫入信息。

區別:

Reader 和Writer要解決的,最主要的問題就是國際化。原先的I/O類庫只支持8位的字節流,因此不可能很好地處理16位的Unicode字符流。 Unicode是國際化的字符集(更何況Java內置的char就是16位的Unicode字符),這樣加了Reader和Writer之后,所有的 I/O就都支持Unicode了。此外新類庫的性能也比舊的好。

但是,Read和Write并不是取代InputStream和 OutputStream,有時,你還必須同時使用"基于byte的類"和"基于字符的類"。為此,它還提供了兩個"適配器(adapter)"類。 InputStreamReader負責將InputStream轉化成Reader,而OutputStreamWriter則將 OutputStream轉化成Writer。

一.流的層次結構 

定義:

(1)java將讀取數據對象成為輸入流,能向其寫入的對象叫輸出流。結構圖如下:輸入流:



輸出流



二.InputStream類 

 

inputstream類和outputstream類都為抽象類,不能創建對象,可以通過子類來實例化。

InputStream是輸入字節數據用的類,所以InputStream類提供了3種重載的read方法.Inputstream類中的常用方法:

(1)public abstract int read( ):讀取一個byte的數據,返回值是高位補0的int類型值。 

 

(2)public int read(byte b[ ]):讀取b.length個字節的數據放到b數組中。返回值是讀取的字節數。該方法實際上是調用下一個方法實現的 

 (3)public int read(byte b[ ], int off, int len):從輸入流中最多讀取len個字節的數據,存放到偏移量為off的b數組中。 
(4) public int available( ):返回輸入流中可以讀取的字節數。注意:若輸入阻塞,當前線程將被掛起,如果InputStream對象調用這個方法的話,它只會返回0,這個方法必須由繼承InputStream類的子類對象調用才有用, 

 (5) public long skip(long n):忽略輸入流中的n個字節,返回值是實際忽略的字節數, 跳過一些字節來讀取 

 
(6) public int close( ) :我們在使用完后,必須對我們打開的流進行關閉. 
三.OutputStream類 
OutputStream提供了3個write方法來做數據的輸出,這個是和InputStream是相對應的。 

 1. public void write(byte b[ ]):將參數b中的字節寫到輸出流。 

 

2. public void write(byte b[ ], int off, int len) :將參數b的從偏移量off開始的len個字節寫到輸出流。 

3. public abstract void write(int b) :先將int轉換為byte類型,把低字節寫入到輸出流中。 

 4. public void flush( ) : 將數據緩沖區中數據全部輸出,并清空緩沖區。 

 

5. public void close( ) : 關閉輸出流并釋放與流相關的系統資源。 

 注意: 

 

1. 上述各方法都有可能引起異常。 
2. InputStream和OutputStream都是抽象類,不能創建這種類型的對象。 
四.FileInputStream類 
FileInputStream類是InputStream類的子類,用來處理以文件作為數據輸入源的數據流。使用方法: 
方式1: 

 File fin=new File("d:/abc.txt"); 

 

 FileInputStream in=new FileInputStream(fin); 

 

方式2: 

 

 FileInputStream in=new 

 

 FileInputStream("d: /abc.txt"); 

 

方式3: 

 

構造函數將 FileDescriptor()對象作為其參數。 

 

FileDescriptor() fd=new FileDescriptor(); 



作者: 222.67.6.*  2007-2-8 10:45   回復此發言  


14 回復:java io


 

FileInputStream f2=new FileInputStream(fd); 

五.FileOutputStream類 

 

FileOutputStream類用來處理以文件作為數據輸出目的數據流;一個表示文件名的字符串,也可以是File或FileDescriptor對象。 

 

創建一個文件流對象有兩種方法: 

 

方式1: 

 

File f=new File("d:/abc.txt"); 

 

FileOutputStream out=new FileOutputStream (f); 

 

方式2: 

 

 FileOutputStream out=new 

 

 FileOutputStream("d:/abc.txt"); 

 

方式3:構造函數將 FileDescriptor()對象作為其參數。 

 

FileDescriptor() fd=new FileDescriptor(); 

 

FileOutputStream f2=new FileOutputStream(fd); 

 

方式4:構造函數將文件名作為其第一參數,將布爾值作為第二參數。 

 

FileOutputStream f=new FileOutputStream("d:/abc.txt",true); 

 

注意: 

 

(1)文件中寫數據時,若文件已經存在,則覆蓋存在的文件;(2)的讀/寫操作結束時,應調用close方法關閉流。 

 

 

 

舉例:2-1 

 

六.File類 

 

File類與InputStream / OutputStream類同屬于一個包,它不允許訪問文件內容。 

 

File類主要用于命名文件、查詢文件屬性和處理文件目錄。 

 

舉例:2-2 

 

七.從一個流構造另一個流 

 

java的流類提供了結構化方法,如,底層流和高層過濾流。 

 

而高層流不是從輸入設備讀取,而是從其他流讀取。同樣高層輸出流也不是寫入輸出設備,而是寫入其他流。 

 

使 用"分層對象(layered objects)",為單個對象動態地,透明地添加功能的做法,被稱為Decorator Pattern。 Decorator模式要求所有包覆在原始對象之外的對象,都必須具有與之完全相同的接口。這使得decorator的用法變得非常的透明--無論對象是 否被decorate過,傳給它的消息總是相同的。這也是Java I/O類庫要有"filter(過濾器)"類的原因:抽象的"filter"類是所有 decorator的基類。Decorator模式常用于如下的情形:如果用繼承來解決各種需求的話,類的數量會多到不切實際的地步。Java的I/O類 庫需要提供很多功能的組合,于是decorator模式就有了用武之地。 

 

為InputStream和OutputStream定義decorator類接口的類,分別是FilterInputStream和FilterOutputStream。

7.1 FilterInputStream

FilterInputStream的種類 

 


 
 
類 

 


 
 功能 

 


 
 構造函數的參數 

 


 
 
 
用法 

 


 
 
 
DataInputStream 

 


 
 與DataOutputStream配合使用,這樣你就能以一種"可攜帶的方式(portable fashion)"從流里讀取primitives了(int,char,long等) 

 


 
 InputStream 

 


 
 
 
包含了一整套讀取primitive數據的接口。 

 


 
 
 
BufferedInputStream 

 


 
 用這個類來解決"每次要用數據的時候都要進行物理讀取"的問題。你的意思是"用緩沖區。" 

 


 
 InputStream,以及可選的緩沖區的容量 

 


 
 
 
它本身并不提供接口,只是提供一個緩沖區。需要連到一個"有接口的對象(interface object)"。 

 


 
 
 
LineNumberInputStream 

 


 
 跟蹤輸入流的行號;有getLineNumber( )和setLineNumber(int)方法 

 


 
 InputStream 

 


 
 
 
只是加一個行號,所以還得連一個"有接口的對象"。 

 


 
 
 
PushbackInputStream 

 


 
 有一個"彈壓單字節"的緩沖區(has a one byte push-back buffer),這樣你就能把最后讀到的那個字節再壓回去了。 

 


 
 InputStream 

 


 
 
 
主要用于編譯器的掃描程序??赡苁菫橹С諮ava的編譯器而設計的。用的機會不多。 



作者: 222.67.6.*  2007-2-8 10:45   回復此發言  


15 回復:java io


 


 
 
 


 

 

 

FilterOutputStream的種類 

 


 
 
類 

 


 
 功能 

 


 
 構造函數的參數 

 


 
 
 
用法 

 


 
 
 
DataOutputStream 

 


 
 與DataInputStream配合使用,這樣你就可以用一種"可攜帶的方式(portable fashion)"往流里寫primitive了(int, char, long,等) 

 


 
 OutputStream 

 


 
 
 
包括寫入primitive數據的全套接口。 

 


 
 
 
PrintStream 

 


 
 負責生成帶格式的輸出(formatted output)。DataOutputStrem負責數據的存儲,而PrintStream負責數據的顯示。 

 


 
 一個OutputStream以及一個可選的boolean值。這個boolean值表示,要不要清空換行符后面的緩沖區。 

 


 
 
 
應該是OutputStream對象的最終包覆層。用的機會很多。 

 


 
 
 
BufferedOutputStream 

 


 
 用 這個類解決"每次往流里寫數據,都要進行物理操作"的問題。也就是說"用緩沖區"。用flush( )清空緩沖區。 

 


 
 OutputStream, 以及一個可選的緩沖區大小 

 


 
 
 
本身并不提供接口,只是加了一個緩沖區。需要鏈接一個有接口的對象。 

 


 
 
 


 

 

 

 

DataInputStream類對象可以讀取各種類型的數據。 

 

DataOutputStream類對象可以寫各種類型的數據; 

 

創建這兩類對象時,必須使新建立的對象指向構造函數中的參數對象。例如: 

 

FileInputStream in=new FileInputStream("d:/abc.txt"); 

 

DataInputStream din=new DataInputStream(in); 

 

7.2BufferInputStream和bufferOutputStream 

 

允許程序在不降低系統性能的情況下一次一個字節的從流中讀取數據。 

 

BufferInputstream定義了兩種構造函數 

 

(1) BufferInputStream b= new BufferInputstream(in); 

 

(2) BufferInputStream b=new BufferInputStream(in,size) 

 

 第二個參數表示指定緩沖器的大小。 

 

同樣BufferOutputStream也有兩種構造函數。一次一個字節的向流中寫數據。 

 

 

 

7.3printstream

用于寫入文本或基本類型 

 

兩種構造函數方法: 

 

PrintStream ps=new PrintStream(out); 

 

PrintStream ps=new PrintStream(out, autoflush) 

 

第二個參數為布爾值,控制每次輸出換行符時java是否刷新輸出流。 

 

 

 

 

 

 

 

八.字符流的讀取和寫入 

 

java.io.Reader 和 java.io.InputStream 組成了 Java 輸入類。Reader 用于讀入16位字符,也就是 Unicode 編碼的字符;而 InputStream 用于讀入 ASCII 字符和二進制數據。
Reader的體系結構



(1) FileReader 

 

 FileReader主要用來讀取字符文件,使用缺省的字符編碼,有三種構造函數: 

 

 --將文件名作為字符串 

 

 FileReader f=new FileReader(“c:/temp.txt”); 

 

--構造函數將File對象作為其參數。 

 

 File f=new file(“c:/temp.txt”); 

 

FileReader f1=new FileReader(f); 

 

--構造函數將FileDescriptor對象作為參數 

 

FileDescriptor() fd=new FileDescriptor() 

 

FileReader f2=new FileReader(fd); 

 

(2) charArrayReader 

 

 將字符數組作為輸入流,構造函數為: 

 

public CharArrayReader(char[] ch); 

 

(3) StringReader 

 

 讀取字符串,構造函數如下: 

 

public StringReader(String s); 

 

(4) InputStreamReader 

 

從輸入流讀取字節,在將它們轉換成字符。 

 

 Public inputstreamReader(inputstream is); 



作者: 222.67.6.*  2007-2-8 10:45   回復此發言  


16 回復:java io


 

(5) FilterReader 

 

允許過濾字符流 

 

protected filterReader(Reader r); 

 

(6) BufferReader 

 

 接受Reader對象作為參數,并對其添加字符緩沖器,使用readline()方法可以讀取一行。 

 

Public BufferReader(Reader r); 

 

 

 

Writer類體系結構



(1) FileWrite 

 

 將字符類型數據寫入文件,使用缺省字符編碼和緩沖器大小。 

 

Public FileWrite(file f); 

 

(2)chararrayWrite() 

 

 將字符緩沖器用作輸出。 

 

 Public CharArrayWrite(); 

 

(3) PrintWrite 

 

 生成格式化輸出 

 

public PrintWriter(outputstream os); 

 

(4) filterWriter 

 

 用于寫入過濾字符流 

 

protected FilterWriter(Writer w);  

FilterOutputStream的種類  

  
 
類 

 


 
 功能 

 


 
 構造函數的參數 

 


 
 
 
用法 

 


 
 
 
DataOutputStream 

 


 
 與DataInputStream配合使用,這樣你就可以用一種"可攜帶的方式(portable fashion)"往流里寫primitive了(int, char, long,等) 

 


 
 OutputStream 

 


 
 
 
包括寫入primitive數據的全套接口。 

 


 
 
 
PrintStream 

 


 
 負責生成帶格式的輸出(formatted output)。DataOutputStrem負責數據的存儲,而PrintStream負責數據的顯示。 

 


 
 一個OutputStream以及一個可選的boolean值。這個boolean值表示,要不要清空換行符后面的緩沖區。 

 


 
 
 
應該是OutputStream對象的最終包覆層。用的機會很多。 

 


 
 
 
BufferedOutputStream 

 


 
 用 這個類解決"每次往流里寫數據,都要進行物理操作"的問題。也就是說"用緩沖區"。用flush( )清空緩沖區。 

 


 
 OutputStream, 以及一個可選的緩沖區大小 

 


 
 
 
本身并不提供接口,只是加了一個緩沖區。需要鏈接一個有接口的對象。 

 


 
 
 


 

 

 

 

DataInputStream類對象可以讀取各種類型的數據。 

 

DataOutputStream類對象可以寫各種類型的數據; 

 

創建這兩類對象時,必須使新建立的對象指向構造函數中的參數對象。例如: 

 

FileInputStream in=new FileInputStream("d:/abc.txt"); 

 

DataInputStream din=new DataInputStream(in); 

 

7.2BufferInputStream和bufferOutputStream 

 

允許程序在不降低系統性能的情況下一次一個字節的從流中讀取數據。 

 

BufferInputstream定義了兩種構造函數 

 

(1) BufferInputStream b= new BufferInputstream(in); 

 

(2) BufferInputStream b=new BufferInputStream(in,size) 

 

 第二個參數表示指定緩沖器的大小。 

 

同樣BufferOutputStream也有兩種構造函數。一次一個字節的向流中寫數據。 

 

 

 

7.3printstream

用于寫入文本或基本類型 

 

兩種構造函數方法: 

 

PrintStream ps=new PrintStream(out); 

 

PrintStream ps=new PrintStream(out, autoflush) 

 

第二個參數為布爾值,控制每次輸出換行符時java是否刷新輸出流。 

 

 

 

 

 

 

 

八.字符流的讀取和寫入 

 

java.io.Reader 和 java.io.InputStream 組成了 Java 輸入類。Reader 用于讀入16位字符,也就是 Unicode 編碼的字符;而 InputStream 用于讀入 ASCII 字符和二進制數據。
Reader的體系結構



(1) FileReader 

 

 FileReader主要用來讀取字符文件,使用缺省的字符編碼,有三種構造函數: 

 

 --將文件名作為字符串 

 

 FileReader f=new FileReader(“c:/temp.txt”); 

 

--構造函數將File對象作為其參數。 

 

 File f=new file(“c:/temp.txt”); 

 

FileReader f1=new FileReader(f); 

 

--構造函數將FileDescriptor對象作為參數 

 

FileDescriptor() fd=new FileDescriptor() 

 

FileReader f2=new FileReader(fd); 

 

(2) charArrayReader 

 

 將字符數組作為輸入流,構造函數為: 

 

public CharArrayReader(char[] ch); 

 

(3) StringReader 

 

 讀取字符串,構造函數如下: 

 

public StringReader(String s); 

 

(4) InputStreamReader 

 

從輸入流讀取字節,在將它們轉換成字符。 

 

 Public inputstreamReader(inputstream is); 

 

(5) FilterReader 

 

允許過濾字符流 

 

protected filterReader(Reader r); 

 

(6) BufferReader 

 

 接受Reader對象作為參數,并對其添加字符緩沖器,使用readline()方法可以讀取一行。 

 

Public BufferReader(Reader r); 

 

 

 

Writer類體系結構



(1) FileWrite 

 

 將字符類型數據寫入文件,使用缺省字符編碼和緩沖器大小。 

 

Public FileWrite(file f); 

 

(2)chararrayWrite() 

 

 將字符緩沖器用作輸出。 

 

 Public CharArrayWrite(); 

 

(3) PrintWrite 

 

 生成格式化輸出 

 

public PrintWriter(outputstream os); 

 

(4) filterWriter 

 

 用于寫入過濾字符流 

 

protected FilterWriter(Writer w);




作者: 222.67.6.*  2007-2-8 10:45   回復此發言  


17 java io simple code

13-1

import java.io.*;
class FileCopy {
 public static void main(String[] args) throw Exception {
 File InputStream input = new FileInputStream("java13.txt");
 //輸入當前目錄下的java13.txt文件

 FileOutputStream output = new File OutputStream("java.bak");
 //輸出到當前目錄下的java13.bak文件
 int size = input.available(); //檢查輸入字節數
 System.out.println("可輸入字節數為:" + size);
 for(int i = 0; i < size; i++) {
 output.write(input.read()); //拷貝到另一個文件
 }
 input.close();
 output.close();
 }
}


13-2

import java.io.*;
class CopyFile {
 public static void main(String[] args) throw Exception {
 FileReader fr = new FileReader("java13.txt");
 //輸入當前目錄下的java13.txt文件

 FileWriter fw = new File FileWriter("java.bak");
 //輸出到當前目錄下的java13.bak文件
 int ch;
 while((ch = fr.read())! = -1) {
 fw.write(ch); //拷貝
 }
 fr.close();
 fw.close();
 }
}

13-3

import java.io.*;
import java.util.*;

class ByteArrayOutputStreamTest {
 public static void main(String[] args) throw Exception { 
 ByteArrayOutputStream b = new ByteArrayOutputStream();
 System.out.println("請輸入七個字符,然后按回車");
 
 While(b.size() != 7) {
 b.write(System.in.read()); //b.size()返回b里的存有的字節數
 }
 System.out.println(b.toString()); //把b變成字符串輸出
 byte arr[] = b.toByteArray(); //把b存入字節數組arr[]
 for(int i = 0; i < arr.length; i++)
 System.out.print((char)arr[i]);
 
 System.out.println();
 OutputStream f = new FileOutputStream("test.doc");
 b.writeTo(f); //把b的內容拷貝到f里去
 b.reset(); //reset()之后,再來輸入就從b的開始寫入
 }
}


13-4

import java.io.*;
public class ReaderWriter {
 public static void main(String[] args) throw IOException {
 echo(new InputStreamReader(System.in),
 new OutputStreamWriter(System.out));
 }

public static void echo(InputStreamReader is, OutputStreamWriter os) 

throws IOException {
 try {
 while(true) {
 //在MS-DOS窗口中運行一個中文平臺,輸入中文
 //CTRL-Z結束中文輸入
 int i = is.read(); //輸入流結束,返回-1
 if (i == -1) break;
 char c = (char) i;
 os.write©;
 }
 } catch(IOException e) {
 System.err.println(e);
 }
 os.flush();
 System.out.println("結束!");
 }
}

13-5

import java.io.*;
class FileTesting {
 public static void main(String args[]) {
 File f = new File("/temp/java12.txt");
 if (f.exists() == true) {
 System.out.println("這個文件存在。");
 System.out.println("文件名是:" + f.getName());
 System.out.println("文件路徑是:" + f.getPath());
 System.out.println("最后的修改日期是:" + f.lastModified());
 System.out.println("文件長度是:" + f.length());
 }
 }
}