通過(guò)數(shù)據(jù)流、序列化和文件系統(tǒng)提供系統(tǒng)輸入和輸出。 Java 把這些不同來(lái)源和目標(biāo)的數(shù)據(jù)都統(tǒng)一抽象為數(shù)據(jù)流。Java 語(yǔ)言的輸入輸出功能是十分強(qiáng)大而靈活的,美中不足的是看上去輸入輸出的代碼并不是很簡(jiǎn)潔,因?yàn)槟阃枰b許多不同的對(duì)象。 在 Java 類庫(kù)中,IO 部分的內(nèi)容是很龐大的,因?yàn)樗婕暗念I(lǐng)域很廣泛:標(biāo)準(zhǔn)輸入輸出,文件的操作,網(wǎng)絡(luò)上的數(shù)據(jù)流,字符串流,對(duì)象流,zip 文件流。
按流向分: 輸入流: 程序可以從中讀取數(shù)據(jù)的流。 輸出流: 程序能向其中寫(xiě)入數(shù)據(jù)的流。 按數(shù)據(jù)傳輸單位分: 字節(jié)流: 以字節(jié)為單位傳輸數(shù)據(jù)的流 字符流: 以字符為單位傳輸數(shù)據(jù)的流 按功能分: 節(jié)點(diǎn)流: 用于直接操作目標(biāo)設(shè)備的流 過(guò)濾流: 是對(duì)一個(gè)已存在的流的鏈接和封裝,通過(guò)對(duì)數(shù)據(jù)進(jìn)行處理為程序提供功能強(qiáng)大、靈活的讀寫(xiě)功能。
JDK 所提供的所有流類位于 java.io 包中,都分別繼承自以下四種抽象流類: InputStream:繼承自 InputStream 的流都是用于向程序中輸入數(shù)據(jù)的,且數(shù)據(jù)單位都是字節(jié)(8位)。 OutputSteam:繼承自 OutputStream 的流都是程序用于向外輸出數(shù)據(jù)的,且數(shù)據(jù)單位都是字節(jié)(8位)。 Reader:繼承自 Reader 的流都是用于向程序中輸入數(shù)據(jù)的,且數(shù)據(jù)單位都是字符(16位)。 Writer:繼承自 Writer 的流都是程序用于向外輸出數(shù)據(jù)的,且數(shù)據(jù)單位都是字符(16位)。
java 語(yǔ)言的輸入輸出功能是十分強(qiáng)大而靈活的,美中不足的是看上去輸入輸出的代碼并不是很簡(jiǎn)潔,因?yàn)槟阃枰b許多不同的對(duì)象。在 Java 類庫(kù)中,IO 部分的內(nèi)容是很龐大的,因?yàn)樗婕暗念I(lǐng)域很廣泛:標(biāo)準(zhǔn)輸入輸出,文件的操作,網(wǎng)絡(luò)上的數(shù)據(jù)流,字符串流,對(duì)象流,zip 文件流....本文的目的是為大家做一個(gè)簡(jiǎn)要的介紹。 流是一個(gè)很形象的概念,當(dāng)程序需要讀取數(shù)據(jù)的時(shí)候,就會(huì)開(kāi)啟一個(gè)通向數(shù)據(jù)源的流,這個(gè)數(shù)據(jù)源可以是文件,內(nèi)存,或是網(wǎng)絡(luò)連接。類似的,當(dāng)程序需要寫(xiě)入數(shù)據(jù)的時(shí)候,就會(huì)開(kāi)啟一個(gè)通向目的地的流。這時(shí)候你就可以想象數(shù)據(jù)好像在這其中“流”動(dòng)一樣,如下圖:
http://wiki.jikexueyuan.com/project/java-special-topic/images/5.gif" alt="" />
Java 中的流分為兩種,一種是字節(jié)流,另一種是字符流,分別由四個(gè)抽象類來(lái)表示(每種流包括輸入和輸出兩種所以一共四個(gè)):InputStream,OutputStream,Reader,Writer。Java 中其他多種多樣變化的流均是由它們派生出來(lái)的: stream 代表的是任何有能力產(chǎn)出數(shù)據(jù)的數(shù)據(jù)源,或是任何有能力接收數(shù)據(jù)的接收源。在 Java 的 IO 中,所有的 stream(包括 Inputstream 和 Out stream)都包括兩種類型: (1)字節(jié)流 表示以字節(jié)為單位從 stream 中讀取或往 stream 中寫(xiě)入信息,即 io 包中的 inputstream 類和 outputstream 類的派生類。通常用來(lái)讀取二進(jìn)制數(shù)據(jù),如圖象和聲音。 (2)字符流 以 Unicode 字符為導(dǎo)向的 stream,表示以 Unicode 字符為單位從 stream 中讀取或往 stream 中寫(xiě)入信息。 區(qū)別: Reader 和 Writer 要解決的,最主要的問(wèn)題就是國(guó)際化。原先的 I/O 類庫(kù)只支持8位的字節(jié)流,因此不可能很好地處理16位的 Unicode 字符流。Unicode 是國(guó)際化的字符集(更何況 Java 內(nèi)置的 char 就是16位的 Unicode 字符),這樣加了 Reader 和 Writer 之后,所有的 I/O 就都支持 Unicode 了。此外新類庫(kù)的性能也比舊的好。 但是,Read 和 Write 并不是取代 InputStream 和 OutputStream,有時(shí),你還必須同時(shí)使用"基于 byte 的類"和"基于字符的類"。為此,它還提供了兩個(gè)"適配器(adapter)"類。InputStreamReader 負(fù)責(zé)將 InputStream 轉(zhuǎn)化成 Reader,而 OutputStreamWriter 則將 OutputStream 轉(zhuǎn)化成 Writer。 一.流的層次結(jié)構(gòu) 定義: (1)java 將讀取數(shù)據(jù)對(duì)象成為輸入流,能向其寫(xiě)入的對(duì)象叫輸出流。結(jié)構(gòu)圖如下:
http://wiki.jikexueyuan.com/project/java-special-topic/images/6.gif" alt="" />
輸入流
http://wiki.jikexueyuan.com/project/java-special-topic/images/7.gif" alt="" />
輸出流
二.InputStream 類 inputstream 類和 outputstream 類都為抽象類,不能創(chuàng)建對(duì)象,可以通過(guò)子類來(lái)實(shí)例化。 InputStream 是輸入字節(jié)數(shù)據(jù)用的類,所以 InputStream 類提供了3種重載的 read 方法.Inputstream 類中的常用方法: (1)public abstract int read( ):讀取一個(gè) byte 的數(shù)據(jù),返回值是高位補(bǔ)0的 int 類型值。 (2)public int read(byte b[ ]):讀取 b.length 個(gè)字節(jié)的數(shù)據(jù)放到b數(shù)組中。返回值是讀取的字節(jié)數(shù)。該方法實(shí)際上是調(diào)用下一個(gè)方法實(shí)現(xiàn)的 (3)public int read(byte b[ ], int off, int len):從輸入流中最多讀取 len 個(gè)字節(jié)的數(shù)據(jù),存放到偏移量為 off 的 b 數(shù)組中。 (4)public int available( ):返回輸入流中可以讀取的字節(jié)數(shù)。注意:若輸入阻塞,當(dāng)前線程將被掛起,如果 InputStream 對(duì)象調(diào)用這個(gè)方法的話,它只會(huì)返回0,這個(gè)方法必須由繼承 InputStream 類的子類對(duì)象調(diào)用才有用, (5)public long skip(long n):忽略輸入流中的 n 個(gè)字節(jié),返回值是實(shí)際忽略的字節(jié)數(shù), 跳過(guò)一些字節(jié)來(lái)讀取 (6)public int close( ) :我們?cè)谑褂猛旰?,必須?duì)我們打開(kāi)的流進(jìn)行關(guān)閉. 三.OutputStream 類 OutputStream 提供了3個(gè) write 方法來(lái)做數(shù)據(jù)的輸出,這個(gè)是和 InputStream 是相對(duì)應(yīng)的。
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream(fin);
方式2:
FileInputStream in=new
FileInputStream("d: /abc.txt");
方式3: 構(gòu)造函數(shù)將 FileDescriptor()對(duì)象作為其參數(shù)。
FileDescriptor() fd=new FileDescriptor();
FileInputStream f2=new FileInputStream(fd);
五.FileOutputStream 類 FileOutputStream 類用來(lái)處理以文件作為數(shù)據(jù)輸出目的數(shù)據(jù)流;一個(gè)表示文件名的字符串,也可以是 File 或 FileDescriptor 對(duì)象。 創(chuàng)建一個(gè)文件流對(duì)象有兩種方法: 方式1:
File f=new File("d:/abc.txt");
FileOutputStream out=new FileOutputStream (f);
方式2:
FileOutputStream out=new
FileOutputStream("d:/abc.txt");
方式3:構(gòu)造函數(shù)將 FileDescriptor()對(duì)象作為其參數(shù)。
FileDescriptor() fd=new FileDescriptor();
FileOutputStream f2=new FileOutputStream(fd);
方式4:構(gòu)造函數(shù)將文件名作為其第一參數(shù),將布爾值作為第二參數(shù)。
FileOutputStream f=new FileOutputStream("d:/abc.txt",true);
注意: (1)文件中寫(xiě)數(shù)據(jù)時(shí),若文件已經(jīng)存在,則覆蓋存在的文件;(2)的讀/寫(xiě)操作結(jié)束時(shí),應(yīng)調(diào)用 close 方法關(guān)閉流。 舉例:2-1 六.File 類 File 類與 InputStream / OutputStream 類同屬于一個(gè)包,它不允許訪問(wèn)文件內(nèi)容。 File 類主要用于命名文件、查詢文件屬性和處理文件目錄。 舉例:2-2 七.從一個(gè)流構(gòu)造另一個(gè)流 java 的流類提供了結(jié)構(gòu)化方法,如,底層流和高層過(guò)濾流。 而高層流不是從輸入設(shè)備讀取,而是從其他流讀取。同樣高層輸出流也不是寫(xiě)入輸出設(shè)備,而是寫(xiě)入其他流。 使用"分層對(duì)象(layered objects)",為單個(gè)對(duì)象動(dòng)態(tài)地,透明地添加功能的做法,被稱為 Decorator Pattern。Decorator 模式要求所有包覆在原始對(duì)象之外的對(duì)象,都必須具有與之完全相同的接口。這使得 decorator 的用法變得非常的透明--無(wú)論對(duì)象是否被 decorate 過(guò),傳給它的消息總是相同的。這也是 Java I/O 類庫(kù)要有"filter(過(guò)濾器)"類的原因:抽象的"filter"類是所有 decorator 的基類。Decorator 模式常用于如下的情形:如果用繼承來(lái)解決各種需求的話,類的數(shù)量會(huì)多到不切實(shí)際的地步。Java 的 I/O 類庫(kù)需要提供很多功能的組合,于是 decorator 模式就有了用武之地。 為 InputStream 和 OutputStream 定義 decorator 類接口的類,分別是 FilterInputStream 和 FilterOutputStream。
http://wiki.jikexueyuan.com/project/java-special-topic/images/66.png" alt="" />
http://wiki.jikexueyuan.com/project/java-special-topic/images/67.png" alt="" />
DataInputStream 類對(duì)象可以讀取各種類型的數(shù)據(jù)。 DataOutputStream 類對(duì)象可以寫(xiě)各種類型的數(shù)據(jù); 創(chuàng)建這兩類對(duì)象時(shí),必須使新建立的對(duì)象指向構(gòu)造函數(shù)中的參數(shù)對(duì)象。例如:
FileInputStream in=new FileInputStream("d:/abc.txt");
DataInputStream din=new DataInputStream(in);
7.2BufferInputStream 和 bufferOutputStream 允許程序在不降低系統(tǒng)性能的情況下一次一個(gè)字節(jié)的從流中讀取數(shù)據(jù)。 BufferInputstream 定義了兩種構(gòu)造函數(shù) (1)BufferInputStream b= new BufferInputstream(in); (2)BufferInputStream b=new BufferInputStream(in,size) 第二個(gè)參數(shù)表示指定緩沖器的大小。 同樣 BufferOutputStream 也有兩種構(gòu)造函數(shù)。一次一個(gè)字節(jié)的向流中寫(xiě)數(shù)據(jù)。 7.3printstream 用于寫(xiě)入文本或基本類型 兩種構(gòu)造函數(shù)方法: PrintStream ps=new PrintStream(out); PrintStream ps=new PrintStream(out, autoflush) 第二個(gè)參數(shù)為布爾值,控制每次輸出換行符時(shí) java 是否刷新輸出流。 八.字符流的讀取和寫(xiě)入 java.io.Reader 和 java.io.InputStream 組成了 Java 輸入類。Reader 用于讀入16位字符,也就是 Unicode 編碼的字符;而 InputStream 用于讀入 ASCII 字符和二進(jìn)制數(shù)據(jù)。
http://wiki.jikexueyuan.com/project/java-special-topic/images/10.gif" alt="" />
Reader 體系結(jié)構(gòu) (1)FileReader FileReader 主要用來(lái)讀取字符文件,使用缺省的字符編碼,有三種構(gòu)造函數(shù): --將文件名作為字符串
FileReader f=new FileReader(“c:/temp.txt”);
--構(gòu)造函數(shù)將 File 對(duì)象作為其參數(shù)。
File f=new file(“c:/temp.txt”);
FileReader f1=new FileReader(f);
--構(gòu)造函數(shù)將 FileDescriptor 對(duì)象作為參數(shù)
FileDescriptor() fd=new FileDescriptor()
FileReader f2=new FileReader(fd);
(2)charArrayReader 將字符數(shù)組作為輸入流,構(gòu)造函數(shù)為:
public CharArrayReader(char[] ch);
(3)StringReader 讀取字符串,構(gòu)造函數(shù)如下:
public StringReader(String s);
(4)InputStreamReader 從輸入流讀取字節(jié),在將它們轉(zhuǎn)換成字符。
Public inputstreamReader(inputstream is);
(5)FilterReader 允許過(guò)濾字符流
protected filterReader(Reader r);
(6)BufferReader 接受 Reader 對(duì)象作為參數(shù),并對(duì)其添加字符緩沖器,使用readline()方法可以讀取一行。
Public BufferReader(Reader r);
http://wiki.jikexueyuan.com/project/java-special-topic/images/11.gif" alt="" />
Writer 類體系結(jié)構(gòu) (1)FileWrite 將字符類型數(shù)據(jù)寫(xiě)入文件,使用缺省字符編碼和緩沖器大小。
Public FileWrite(file f);
(2)chararrayWrite() 將字符緩沖器用作輸出。
Public CharArrayWrite();
(3)PrintWrite 生成格式化輸出
public PrintWriter(outputstream os);
(4)filterWriter 用于寫(xiě)入過(guò)濾字符流
protected FilterWriter(Writer w);
http://wiki.jikexueyuan.com/project/java-special-topic/images/68.png" alt="" />
DataInputStream 類對(duì)象可以讀取各種類型的數(shù)據(jù)。 DataOutputStream 類對(duì)象可以寫(xiě)各種類型的數(shù)據(jù); 創(chuàng)建這兩類對(duì)象時(shí),必須使新建立的對(duì)象指向構(gòu)造函數(shù)中的參數(shù)對(duì)象。例如:
FileInputStream in=new FileInputStream("d:/abc.txt");
DataInputStream din=new DataInputStream(in);
7.2BufferInputStream 和 bufferOutputStream 允許程序在不降低系統(tǒng)性能的情況下一次一個(gè)字節(jié)的從流中讀取數(shù)據(jù)。 BufferInputstream 定義了兩種構(gòu)造函數(shù) (1)BufferInputStream b= new BufferInputstream(in); (2)BufferInputStream b=new BufferInputStream(in,size) 第二個(gè)參數(shù)表示指定緩沖器的大小。 同樣 BufferOutputStream 也有兩種構(gòu)造函數(shù)。一次一個(gè)字節(jié)的向流中寫(xiě)數(shù)據(jù)。 7.3printstream 用于寫(xiě)入文本或基本類型 兩種構(gòu)造函數(shù)方法: PrintStream ps=new PrintStream(out); PrintStream ps=new PrintStream(out, autoflush) 第二個(gè)參數(shù)為布爾值,控制每次輸出換行符時(shí) java 是否刷新輸出流