鍍金池/ 教程/ Java/ 輸入輸出流
Struts2
Java 泛型
排序算法
Java 內(nèi)存管理
Webservice
Spring
輸入輸出流
Socket
字符串與數(shù)組
面向?qū)ο缶幊?/span>
海量數(shù)據(jù)處理
Hibernate
Netty
基本類型與運(yùn)算符
常見(jiàn)設(shè)計(jì)模式
Java 虛擬機(jī)
Java 多線程
JDBC
搭建 Java 開(kāi)發(fā)環(huán)境
Java 數(shù)據(jù)庫(kù)操作
異常處理
集合類
Servlet 與 JSP

輸入輸出流

Java 輸入輸出流詳解

通過(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 文件流。

1.1、Java 流的分類

按流向分: 輸入流: 程序可以從中讀取數(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ě)功能。

1.2、java.io 常用類

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)的。

  1. public void write(byte b[ ]):將參數(shù) b 中的字節(jié)寫(xiě)到輸出流。
  2. public void write(byte b[ ], int off, int len) :將參數(shù) b 的從偏移量 off 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)到輸出流。
  3. public abstract void write(int b) :先將 int 轉(zhuǎn)換為 byte 類型,把低字節(jié)寫(xiě)入到輸出流中。
  4. public void flush( ) : 將數(shù)據(jù)緩沖區(qū)中數(shù)據(jù)全部輸出,并清空緩沖區(qū)。
  5. public void close( ) : 關(guān)閉輸出流并釋放與流相關(guān)的系統(tǒng)資源。 注意:
  6. 上述各方法都有可能引起異常。
  7. InputStream 和 OutputStream 都是抽象類,不能創(chuàng)建這種類型的對(duì)象。 四.FileInputStream 類 FileInputStream 類是 InputStream 類的子類,用來(lái)處理以文件作為數(shù)據(jù)輸入源的數(shù)據(jù)流。使用方法: 方式1:
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 是否刷新輸出流