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();
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 |
|
主要用於編譯器的掃描程序。可能是為支持Java的編譯器而設計的。用的機會不多。 |
|
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);
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);