OutputStream

OutputStream類是java開發中非常重要的類,是java IO中所有輸出流的父類。該類是一個抽象類,以便用子類對其的具體實現,這也是多態的一種體現。

java的OutputStream的類型

這一類別包括的類決定了我們的輸出往何處去:

一個位元組數組(但沒有String;假定我們可用位元組數組創建一個);

一個檔案;或者一個“管道”。

除此以外,FilterOutputStream為“破壞器”類提供了一個基礎類,它將屬性或者有用的接口同輸出流連線起來。這將在以後討論。

表10.2 OutputStream的類型







ByteArray-OutputStream Creates a buffer in memory. All the data that you send to the stream is placed in this buffer. Optional initial size of the buffer.
To designate the destination of your data. Connect it to a FilterOutputStream object to provide a useful interface.

File-OutputStream For sending information to a file. A String representing the file name, or a File or FileDescriptor object.
To designate the destination of your data. Connect it to a FilterOutputStream object to provide a useful interface.

Piped-OutputStream Any information you write to this automatically ends up as input for the associated PipedInput-Stream. Implements the “piping” concept. PipedInputStream
To designate the destination of your data for multithreading. Connect it to a FilterOutputStream object to provide a useful interface.

Filter-OutputStream Abstract class which is an interface for decorators that provide useful functionality to the other OutputStream classes. See Table 10-4. See Table 10-4.
See Table 10-4.

類 功能 構建器參數/如何使用

ByteArrayOutputStream 在記憶體中創建一個緩衝區。我們傳送給流的所有數據都會置入這個緩衝區。 可選緩衝區的初始大小/用於指出數據的目的地。若將其同FilterOutputStream對象連線到一起,可提供一個有用的接口

FileOutputStream 將信息發給一個檔案 用一個String代表檔案名稱,或選用一個File或FileDescriptor對象/用於指出數據的目的地。

PipedOutputStream 我們寫給它的任何信息都會自動成為相關的PipedInputStream的輸出。實現了“管道化”的概念 PipedInputStream/為多執行緒處理指出自己數據的目的地/將其同FilterOutputStream對象連線到一起,便可提供一個有用的接口

FilterOutputStream 對作為破壞器接口使用的類進行抽象處理;那個破壞器為其他OutputStream類提供了有用的功能。參見表10.4

OutputStream的使用方法

根據寫數據的方式不同,OutputStream主要分成兩類;一類是寫給人看的,一類是供DataInputStream用的。雖然RandomAccessFile的數據格式同DataInputStream和DataOutputStream的相同,但它不屬於OutputStream的。

存儲和恢複數據

PrintWriter會對數據進行格式化,這樣人就能讀懂了。但是如果數據輸出之後,還要恢復出來供其它流用,那你就必須用DataOutputStream來寫數據,再用DataInputStream來讀數據了。當然,它們可以是任何流,不過我們這裡用的是一個經緩衝的檔案。DataOutputStream和DataInputStream是面向byte的,因此這些流必須都是InputStream和OutputStream。

如果數據是用DataOutputStream寫的,那么不管在哪個平台上,DataInputStream都能準確地把它還原出來。這一點真是太有用了,因為沒人知道誰在為平台專屬的數據操心。如果你在兩個平台上都用Java,那這個問題就根本不存在了 。

用DataOutputStream寫String的時候,要想確保將來能用DataInputStream恢復出來,唯一的辦法就是使用UTF-8編碼,也就是像例程第5部分那樣,用writeUTF( )和readUTF( )。UTF-8是Unicode的一種變形。Unicode用兩個位元組來表示一個字元。但是,如果你處理的全部,或主要是ASCII字元(只有7位),那么無論從存儲空間還是從頻寬上看,就都顯得太浪費了,所以UTF-8 用一個位元組表示ASCII字元,用兩或三個位元組表示非ASCII的字元。此外,字元串的長度信息存在(字元串)的頭兩個位元組里。writeUTF( )和readUTF( )用的是Java自己的UTF-8版本(JDK文檔里有關於這個字元集的完整講解,就在這兩個方法的文檔里),所以如果你要用一個Java程式讀取writeUTF( )寫的字元串的話,就必須進行一些特殊處理了。

有了writeUTF( )和readUTF( ),你就能放心地把String和其它數據混在一起交給DataOutputStream了,因為你知道String是以Unicode的形式存儲的,而且可以很方便地用DataOutputStream恢復出來。

writeDouble( )會往流里寫double,而它"影子"readDouble( )則負責把它恢復出來(其它數據也有類似的讀寫方法)。但是要想讓讀取方法能正常工作,你就必須知道流的各個位置上都放了些什麼數據。因為你完全可以把double讀成byte,char,或其它什麼東西。所以要么以固定的格式寫檔案,要么在檔案里提供額外的解釋信息,然後一邊讀數據一邊找數據。先提一下,對於複雜數據的存儲和恢復,對象的序列化可能會比較簡單。

讀寫隨機檔案

正如我們前面所講的,如果不算它實現了DataInput和DataOutput接口,RandomAccessFile幾乎是完全獨立於其它I/O類庫之外的,所以它不能與InputStream和OutputStream合起來用。雖然把ByteArrayInputStream當作"隨機存取的元素(random-access element)"是一件很合情合理的事,但你只能用RandomAccessFile來打開檔案。而且,你只能假定RandomAccessFile已經做過緩衝了,因為即便沒做你也無能為力。

構造函式的第二個參數的意思是:是以唯讀("r") 還是讀寫("rw")方式打開RandomAccessFile。

RandomAccessFile的用法就像是DataInputStream和DataOutputStream的結合(因為它們的接口是等效的)。此外,你還能用seek( )在檔案里上下移動,並進行修改。

隨著JDK 1.4的new I/O的問世,你該考慮一下是不是用"記憶體映射檔案(memory-mapped file)"來代替RandomAccessFile了。

相關詞條

相關搜尋

熱門詞條

聯絡我們