文章目录
1 OutputStream 子类结构1.1 OutputStream 源码分析
2 OutputStream 具体实现类源码分析2.1 ByteArrayOutputStream —— 字节输出流2.2 FileOutputStream —— 文件输出流2.3 PipedOutputStream —— 管道输出流2.4 SocketOutputStream —— 网络输出流2.5 ObjectOutputStream —— 序列化输出流
3 OutputStream 装饰类源码分析3.1 BufferedOutputStream —— 缓冲输出流3.2 DataOutputStream —— 基本类型序列化3.3 GZIPOutputStream3.4 ZIPOutputStream
在 Java InputStream 浅析 一文中,介绍了 InputStream 相关的知识本文将简要介绍 Java 中的 OutputStream 类体系结构
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
留待以后分析