c java 字节流_java 字节流源码解析

1. InputStream

重要方法:

public int read(byte b[], int off, int len) throws IOException {

if (b == null) {

throw new NullPointerException();

} else if (off < 0 || len < 0 || len > b.length - off) {

throw new IndexOutOfBoundsException();

} else if (len == 0) {

return 0;

}

int c = read();

if (c == -1) {

return -1;

}

b[off] = (byte)c;

int i = 1;

try {

for (; i < len ; i++) {

c = read();

if (c == -1) {

break;

}

b[off + i] = (byte)c;

}

} catch (IOException ee) {

}

return i;

}

一个一个字节读取,放到byte数组中

1.1 FileInputStream

重要方法:

// 读取一个字节

public int read() throws IOException {

return read0();

}

// 调用 native 方法

private native int read0() throws IOException;

// 读取b.length的内容

public int read(byte b[]) throws IOException {

return readBytes(b, 0, b.length);

}

public int read(byte b[], int off, int len) throws IOException {

return readBytes(b, off, len);

}

// 调用 native 方法

private native int readBytes(byte b[], int off, int len) throws IOException;

1.2 BufferedInputStream

1.2.1 声明

// 继承自 FilterInputStream

public class BufferedInputStream extends FilterInputStream

1.2.2 构造方法

private static int DEFAULT_BUFFER_SIZE = 8192;

public BufferedInputStream(InputStream in) {

this(in, DEFAULT_BUFFER_SIZE);

}

public BufferedInputStream(InputStream in, int size) {

super(in);

if (size <= 0) {

throw new IllegalArgumentException("Buffer size <= 0");

}

buf = new byte[size];

}

// super(in);

protected FilterInputStream(InputStream in) {

this.in = in;

}

1.2.3 read

public synchronized int read() throws IOException {

if (pos >= count) {

fill();

if (pos >= count)

return -1;

}

// 从buf中读取一个字节

return getBufIfOpen()[pos++] & 0xff;

}

private byte[] getBufIfOpen() throws IOException {

byte[] buffer = buf;

if (buffer == null)

throw new IOException("Stream closed");

return buffer;

}

public synchronized int read(byte b[], int off, int len) throws IOException{

getBufIfOpen(); // Check for closed stream

if ((off | len | (off + len) | (b.length - (off + len))) < 0) {

throw new IndexOutOfBoundsException();

} else if (len == 0) {

return 0;

}

int n = 0;

for (;;) {

int nread = read1(b, off + n, len - n);

if (nread <= 0)

return (n == 0) ? nread : n;

n += nread;

if (n >= len)

return n;

// if not closed but no bytes available, return

InputStream input = in;

if (input != null && input.available() <= 0)

return n;

}

}

private int read1(byte[] b, int off, int len) throws IOException {

int avail = count - pos;

if (avail <= 0) {

/* If the requested length is at least as large as the buffer, and

if there is no mark/reset activity, do not bother to copy the

bytes into the local buffer. In this way buffered streams will

cascade harmlessly. */

if (len >= getBufIfOpen().length && markpos < 0) {

return getInIfOpen().read(b, off, len);

}

fill();

avail = count - pos;

if (avail <= 0) return -1;

}

int cnt = (avail < len) ? avail : len;

System.arraycopy(getBufIfOpen(), pos, b, off, cnt);

pos += cnt;

return cnt;

}

// 归根究底,目的是将数据放入buffer中缓存,下次读取可以直接获取

private void fill() throws IOException {

byte[] buffer = getBufIfOpen();

if (markpos < 0)

pos = 0; /* no mark: throw away the buffer */

else if (pos >= buffer.length) /* no room left in buffer */

if (markpos > 0) { /* can throw away early part of the buffer */

int sz = pos - markpos;

System.arraycopy(buffer, markpos, buffer, 0, sz);

pos = sz;

markpos = 0;

} else if (buffer.length >= marklimit) {

markpos = -1; /* buffer got too big, invalidate mark */

pos = 0; /* drop buffer contents */

} else if (buffer.length >= MAX_BUFFER_SIZE) {

throw new OutOfMemoryError("Required array size too large");

} else { /* grow buffer */

int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?

pos * 2 : MAX_BUFFER_SIZE;

if (nsz > marklimit)

nsz = marklimit;

byte nbuf[] = new byte[nsz];

System.arraycopy(buffer, 0, nbuf, 0, pos);

if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {

// Can't replace buf if there was an async close.

// Note: This would need to be changed if fill()

// is ever made accessible to multiple threads.

// But for now, the only way CAS can fail is via close.

// assert buf == null;

throw new IOException("Stream closed");

}

buffer = nbuf;

}

count = pos;

int n = getInIfOpen().read(buffer, pos, buffer.length - pos);

if (n > 0)

count = n + pos;

}

private int read1(byte[] b, int off, int len) throws IOException {

int avail = count - pos;

if (avail <= 0) {

/* If the requested length is at least as large as the buffer, and

if there is no mark/reset activity, do not bother to copy the

bytes into the local buffer. In this way buffered streams will

cascade harmlessly. */

if (len >= getBufIfOpen().length && markpos < 0) {

return getInIfOpen().read(b, off, len);

}

fill();

avail = count - pos;

if (avail <= 0) return -1;

}

int cnt = (avail < len) ? avail : len;

System.arraycopy(getBufIfOpen(), pos, b, off, cnt);

pos += cnt;

return cnt;

}

2. OutputStream

重要方法:

public void write(byte b[], int off, int len) throws IOException {

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]);

}

}

2.1 FileOutputStream

2.1.1 write

// 写一个字节

public void write(int b) throws IOException {

write(b, append);

}

private native void write(int b, boolean append) throws IOException;

public void write(byte b[]) throws IOException {

writeBytes(b, 0, b.length, append);

}

private native void writeBytes(byte b[], int off, int len, boolean append)

throws IOException;

public void write(byte b[], int off, int len) throws IOException {

writeBytes(b, off, len, append);

}

2.2 BuffedOutputStream

2.2.1 声明

public class BufferedOutputStream extends FilterOutputStream

2.2.2 constructor

// 在内存中申请一个 byte[]

public BufferedOutputStream(OutputStream out) {

this(out, 8192);

}

public BufferedOutputStream(OutputStream out, int size) {

super(out);

if (size <= 0) {

throw new IllegalArgumentException("Buffer size <= 0");

}

buf = new byte[size];

}

2.2.3 write

// 写一个字节

public synchronized void write(int b) throws IOException {

if (count >= buf.length) {

flushBuffer();

}

buf[count++] = (byte)b;

}

// 调用 outputstream 的 write方法

private void flushBuffer() throws IOException {

if (count > 0) {

out.write(buf, 0, count);

count = 0;

}

}

public synchronized void write(byte b[], int off, int len) throws IOException {

if (len >= buf.length) {

/* If the request length exceeds the size of the output buffer,

flush the output buffer and then write the data directly.

In this way buffered streams will cascade harmlessly. */

flushBuffer();

out.write(b, off, len);

return;

}

if (len > buf.length - count) {

flushBuffer();

}

// 首先存放到buffer内存中

System.arraycopy(b, off, buf, count, len);

count += len;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值