1、InputStream和OutputStream2、BufferedInputStream 和 BufferedOutputStream
BufferedInputStream 类的继承与实现关系及对应的成员变量、构造、方法BufferedIOutputStream 类的继承与实现关系及对应的成员变量、构造、方法demo:red读取内容:write写内容:
1、InputStream和OutputStreampublic abstract class InputStream implements Closeable {
// MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
// use when skipping.
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
}
有上面内容可知,InputStream是一个抽象类实现了Closeable接口,,也间接实现了AutoCloseable接口,有一个成员变量MAX_SKIP_BUFFER_SIZE,用于确定跳过时使用的最大缓冲区大小
public abstract class OutputStream implements Closeable, Flushable {
}
由上面可知,OutputStream也是一个抽象类,实现了Closeable, Flushable接口,也间接实现了AutoCloseable接口
2、BufferedInputStream 和 BufferedOutputStream BufferedInputStream 类的继承与实现关系及对应的成员变量、构造、方法public class BufferedInputStream extends FilterInputStream {
// 默认缓冲大小
private static int DEFAULT_BUFFER_SIZE = 8192;
// 最大缓冲大小
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
// 缓冲存储区
protected volatile byte buf[];
private static final
AtomicReferenceFieldUpdater bufUpdater =
AtomicReferenceFieldUpdater.newUpdater
(BufferedInputStream.class, byte[].class, "buf");
protected int count;
protected int pos;
protected int markpos = -1;
protected int marklimit;
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];
}
}
BufferedIOutputStream 类的继承与实现关系及对应的成员变量、构造、方法
public class BufferedOutputStream extends FilterOutputStream {
// 缓冲区大小
protected byte buf[];
protected int count;
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];
}
}
demo:
从一个文件中内容,写入到另外一个文件
public static void main(String[] args) throws IOException {
try(
// 获取缓冲输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E://hello.txt"));
// 获取缓冲输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("hello.txt"));
)
{
// 获取读取的内容数据的长度
int available = bufferedInputStream.available();
System.out.println("available = " + available);
// 存储读取的字节内容
byte[] aa = new byte[available];
int i = 0;
while ((i = bufferedInputStream.read(aa)) != -1){
// 写入读取的字节内容
bufferedOutputStream.write(aa);
}
}
}
获取读取的内容数据的长度:
int available = bufferedInputStream.available();
public synchronized int available() throws IOException {
int n = count - pos;
int avail = getInIfOpen().available();
return n > (Integer.MAX_VALUE - avail)
? Integer.MAX_VALUE
: n + avail;
}
// 判断输入流是否关闭
private InputStream getInIfOpen() throws IOException {
InputStream input = in;
if (input == null)
throw new IOException("Stream closed");
return input;
}
// FileInputStream类中的available()
public int available() throws IOException {
return available0();
}
// FileInputStream类中的available0(),且该方法使用了native修饰
private native int available0() throws IOException;
red读取内容:
// FilterInputStream类里面的read(byte b[]),FilterInputStream类的子类重写了该方法
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
//BufferedInputStream类里面的read(byte b[], int off, int len)
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;
}
}
//BufferedInputStream类里面的read1(byte b[], int off, int len)
private int read1(byte[] b, int off, int len) throws IOException {
int avail = count - pos;
if (avail <= 0) {
// 判断一次读取的长度是否大于缓冲区的容量大小及确定markpos是否小于0
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;
}
private void fill() throws IOException {
// 获取缓冲区
byte[] buffer = getBufIfOpen();
if (markpos < 0)
pos = 0;
else if (pos >= buffer.length)
if (markpos > 0) {
int sz = pos - markpos;
System.arraycopy(buffer, markpos, buffer, 0, sz);
pos = sz;
markpos = 0;
} else if (buffer.length >= marklimit) {
markpos = -1;
pos = 0;
} else if (buffer.length >= MAX_BUFFER_SIZE) {
throw new OutOfMemoryError("Required array size too large");
} else {
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;
}
write写内容:
// FilterOutputStream类里面的write(byte b[]),FilterOutputStream类的子类重写了该方法
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
// BufferedOutputStream类里面的write(byte b[], int off, int len)
public synchronized void write(byte b[], int off, int len) throws IOException {
// 判断是否大于缓冲区的长度
if (len >= buf.length) {
// 刷新缓冲区
flushBuffer();
// 写入数据
out.write(b, off, len);
return;
}
// 判断缓冲区剩余的长度是否大于要写入的内容的长度
if (len > buf.length - count) {
flushBuffer();
}
System.arraycopy(b, off, buf, count, len);
count += len;
}
// 刷新缓冲区
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
// 写入数据
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]);
}
}
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}



