标签:
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]; }
构造函数,无参和有参
无参的其实是设置默认缓冲大小,有参则可以修改,buf则是缓冲数组
private static int DEFAULT_BUFFER_SIZE = 8192;
protected volatile byte buf[];
再看看read()方法
public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }
protected int count;
protected int pos;
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 byte[] getBufIfOpen() throws IOException { byte[] buffer = buf; if (buffer == null) throw new IOException("Stream closed"); return buffer; }
getBufIfOpen()方法buf数组不为空则获取当前buf数组(close方法设空)
protected int markpos = -1;
protected int marklimit;
private InputStream getInIfOpen() throws IOException { InputStream input = in; if (input == null) throw new IOException("Stream closed"); return input; }
相似的getInIfOpen()方法如果in不为空则获取当前in(close方法设空)
没有mark的时候,fill()就是从InputStream中尝试读一个缓冲数组长度到buffer中,count为实际读取长度
说实话这里我想了好久,数组也是对象,除了boolean, byte, short, char, int, long, float, double之外都是对象,new int[5] instanceof Object在IDE中打印出来也确实是true。更改buffer实际就是对buf的操作。
read()读取buf中索引为pos的值并和0xff按位与(为了将-128~-1转为128~255得到0~255),并且pos加1。
看出pos表示buffer中读到的位置,加1后供下次read,超过count的实际读取长度时再次调用fill(),重新读流后pos为0,如果流读完了count为-1,于是return -1
mark我还没用过- -用到了再往下写
标签:
原文地址:http://www.cnblogs.com/wqbill/p/5326749.html