在Java I/O中,抽象類OutputStream是其他輸出流類(如FileOutputStream)的基礎類,分析一下這個類的源碼很有必要。
概要
- public abstract class OutputStream implements Closeable, Flushable
該類使用默認的構造函數,沒有參數。類中定義了1個抽象方法和4個具體方法,其中close()和flush()是對接口中方法的實現(其實是空實現,什麼都沒有)。方法聲明分別如下:
- public abstract void write(int b) throws IOException;
- public void write(byte b[]) throws IOException
- public void write(byte b[], int off, int len) throws IOException
以上三個方法都是用於寫出字節,具體請看下文。還有兩個空實現的方法:
- public void flush() throws IOException {
- }
- public void close() throws IOException {
- }
方法分析
write(int b)
write(byte b[], int off, int len)
- if (b == null) {
- throw new NullPointerException();
- } else if ((off < 0) || (off > b.length) || (len < 0) ||
- ((off + len) > b.length) || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
- }
- for (int i = 0 ; i < len ; i++) {
- write(b[off + i]);
- }
API鼓勵子類提供更高性能的實現方法。在這個方法中,由於字節本身就是8位,沒有超出範圍的情況,所以直接寫入無需轉換。如果傳遞的data爲空,則拋出NullPointerException異常。如果被寫入的部分超出字節數組範圍,拋出IndexOutofBoundsException異常。具體地說,有以下5中情況,也就是if語句當中的5個表達式。除此之外,如果寫入過程出現錯誤,一樣拋出IOException。
write(byte b[])
- public void write(byte b[]) throws IOException {
- write(b, 0, b.length);
- }
有一點需要說明,如果一次寫入的字節數組太大,可能就會是性能下降,至於多少合適,得根據具體情況而定。比如寫入網絡的時候就需要小一點了,如128字節。寫入文件的話,稍大一點1024.
flush()
close()
- try {
- OutputStream out = new FileOutputStream("numbers.dat");
- // Write to the stream...
- out.close( );
- }
- catch (IOException ex) {
- System.err.println(ex);
- }
當然,這樣有個問題,如果在寫入的時候出現異常,那麼輸出流的close方法就不會被執行,也就是不會被關閉。換一種方法;
- OutputStream out = null;
- try {
- out = new FileOutputStream("numbers.dat");
- // Write to the stream...
- }
- catch (IOException ex) {
- System.err.println(ex);
- }
- finally {
- if (out != null) {
- try {
- out.close( );
- }
- catch (IOException ex) {
- System.err.println(ex);
- }
- }
- }
注意到,這裏的OutputStream聲明放到了try語句外面,必須這樣才能被finally中的語句訪問。這樣寫雖然安全,但是有點醜陋就是了。如果不處理異常而是拋出,那麼可以這樣:
- OutputStream out == null;
- try {
- out = new FileOutputStream("numbers.dat");
- // Write to the stream...
- }
- finally {
- if (out != null) out.close( );
- }
一個自定義子類
- import java.io.*;
- public class NullOutputStream extends OutputStream {
- private boolean closed = false;
- public void write(int b) throws IOException {
- if (closed) throw new IOException("Write to closed stream");
- }
- public void write(byte[] data, int offset, int length)
- throws IOException {
- if (data == null) throw new NullPointerException("data is null");
- if (closed) throw new IOException("Write to closed stream");
- }
- public void close( ) {
- closed = true;
- }
- }
這個類重寫了出了flush以外的四個方法,因爲寫入方法什麼都不幹,當然沒必須flush啦。實現很容易懂。不多說明。