1 OutputStream 子類結構
如 InputStream 一樣,OutputStream 也是一個典型的裝飾者模式的示例
它的體系結構和 InputStream 很是相似
OutputStream 比 InputStream 多繼承一個 Flushable 接口,用於將緩衝輸出寫入 underlying stream
1.1 OutputStream 源碼分析
public abstract class OutputStream implements Closeable , Flushable {
public abstract void write ( int b) throws IOException;
public void write ( byte b[ ] ) throws IOException {
write ( b, 0 , b. length) ;
}
public void write ( byte b[ ] , int off, int len) throws IOException { . . . }
public void flush ( ) throws IOException { }
public void close ( ) throws IOException { }
}
2 OutputStream 具體實現類源碼分析
2.1 ByteArrayOutputStream —— 字節輸出流
核心參數:
buf[]:存儲輸出字節的地方,可以自動擴容
count:buf[] 數組,有效內容的最大下標
核心方法:
write(int b):將 int 類型 b 的 低 8 位 存入字節數組中
public class ByteArrayOutputStream extends OutputStream {
protected byte buf[ ] ;
protected int count;
public synchronized void write ( int b) {
ensureCapacity ( count + 1 ) ;
buf[ count] = ( byte ) b;
count += 1 ;
}
public synchronized void write ( byte b[ ] , int off, int len) {
if ( ( off < 0 ) || ( off > b. length) || ( len < 0 ) ||
( ( off + len) - b. length > 0 ) ) {
throw new IndexOutOfBoundsException ( ) ;
}
ensureCapacity ( count + len) ;
System. arraycopy ( b, off, buf, count, len) ;
count += len;
}
public synchronized void writeTo ( OutputStream out) throws IOException {
out. write ( buf, 0 , count) ;
}
public synchronized void reset ( ) { count = 0 ; }
public synchronized byte toByteArray ( ) [ ] {
return Arrays. copyOf ( buf, count) ;
}
public synchronized String toString ( ) {
return new String ( buf, 0 , count) ;
}
public synchronized String toString ( String charsetName) {
return new String ( buf, 0 , count, charsetName) ;
}
public void close ( ) throws IOException {
}
}
2.2 FileOutputStream —— 文件輸出流
核心參數:
append:是否爲 append 模式
path:文件路徑
核心方法:
write(int b, boolean append):寫入一個字節到輸出流
沒有實現 flush 方法
public class FileOutputStream extends OutputStream {
private final FileDescriptor fd;
private final boolean append;
private FileChannel channel;
private final String path;
private final Object closeLock = new Object ( ) ;
private volatile boolean closed = false ;
public FileOutputStream ( File file, boolean append) {
String name = ( file != null ? file. getPath ( ) : null) ;
SecurityManager security = System. getSecurityManager ( ) ;
if ( security != null) {
security. checkWrite ( name) ;
}
if ( name == null) {
throw new NullPointerException ( ) ;
}
if ( file. isInvalid ( ) ) {
throw new FileNotFoundException ( "Invalid file path" ) ;
}
this . fd = new FileDescriptor ( ) ;
fd. attach ( this ) ;
this . append = append;
this . path = name;
open ( name, append) ;
}
private native void open0 ( String name, boolean append) throws FileNotFoundException;
private native void write ( int b, boolean append) throws IOException;
private native void writeBytes ( byte b[ ] , int off, int len, boolean append) throws IOException;
public void close ( ) throws IOException {
synchronized ( closeLock) {
if ( closed) {
return ;
}
closed = true ;
}
if ( channel != null) {
channel. close ( ) ;
}
fd. closeAll ( new Closeable ( ) {
public void close ( ) throws IOException {
close0 ( ) ;
}
} ) ;
}
}
2.3 PipedOutputStream —— 管道輸出流
核心參數:sink,內部依賴輸入流
核心方法:connect(PipedInputStream snk),傳入一個輸入流
public class PipedOutputStream extends OutputStream {
private PipedInputStream sink;
public synchronized void connect ( PipedInputStream snk) throws IOException {
if ( snk == null) {
throw new NullPointerException ( ) ;
} else if ( sink != null || snk. connected) {
throw new IOException ( "Already connected" ) ;
}
sink = snk;
snk. in = - 1 ;
snk. out = 0 ;
snk. connected = true ;
}
public void write ( int b) throws IOException {
if ( sink == null) {
throw new IOException ( "Pipe not connected" ) ;
}
sink. receive ( b) ;
}
public synchronized void flush ( ) throws IOException {
if ( sink != null) {
synchronized ( sink) {
sink. notifyAll ( ) ;
}
}
}
public void close ( ) throws IOException {
if ( sink != null) {
sink. receivedLast ( ) ;
}
}
}
2.4 SocketOutputStream —— 網絡輸出流
class SocketOutputStream extends FileOutputStream {
private AbstractPlainSocketImpl impl = null;
private byte temp[ ] = new byte [ 1 ] ;
private Socket socket = null;
SocketOutputStream ( AbstractPlainSocketImpl impl) throws IOException {
super ( impl. getFileDescriptor ( ) ) ;
this . impl = impl;
socket = impl. getSocket ( ) ;
}
private native void socketWrite0 ( FileDescriptor fd, byte [ ] b, int off,
int len) throws IOException;
public void close ( ) throws IOException {
if ( closing)
return ;
closing = true ;
if ( socket != null) {
if ( ! socket. isClosed ( ) )
socket. close ( ) ;
} else
impl. close ( ) ;
closing = false ;
}
}
2.5 ObjectOutputStream —— 序列化輸出流
3 OutputStream 裝飾類源碼分析
3.1 BufferedOutputStream —— 緩衝輸出流
核心參數:
buf[]:最爲緩衝區
count:緩衝區的已緩存下標
核心方法:
flushBuffer:刷空緩衝區
write:向緩衝區寫字節
public class BufferedOutputStream extends FilterOutputStream {
protected byte buf[ ] ;
protected int count;
public BufferedOutputStream ( OutputStream out, int size) {
super ( out) ;
if ( size <= 0 ) {
throw new IllegalArgumentException ( "Buffer size <= 0" ) ;
}
buf = new byte [ size] ;
}
private void flushBuffer ( ) throws IOException {
if ( count > 0 ) {
out. write ( buf, 0 , count) ;
count = 0 ;
}
}
public synchronized void write ( int b) throws IOException {
if ( count >= buf. length) {
flushBuffer ( ) ;
}
buf[ count++ ] = ( byte ) b;
}
public synchronized void flush ( ) throws IOException {
flushBuffer ( ) ;
out. flush ( ) ;
}
}
3.2 DataOutputStream —— 基本類型序列化
public class DataOutputStream extends FilterOutputStream implements DataOutput {
protected int written;
public final void writeBytes ( String s) throws IOException {
int len = s. length ( ) ;
for ( int i = 0 ; i < len ; i++ ) {
out. write ( ( byte ) s. charAt ( i) ) ;
}
incCount ( len) ;
}
}
3.3 GZIPOutputStream
3.4 ZIPOutputStream