这两个流是带有缓存功能的流(一般读取文件都建议用这两个)
1、BufferInputStream介绍
主要介绍fill()方法(这个方法体现和不带缓存区方法的不同之处)
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); //重要,把操作系统内核数据拷贝到JVM空间,这个是 //一个块的拷贝啊(不在是单字节的读取方法了,当然最后从buffer读取是单字节读取形式,但是和磁盘IO交换 的次数变少了,大大的提示了性能)!!! 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; }
这里设计到几个变量 markpos,pos,marklimit(看过JAVA NIO的很快就知道其他的意思)
markpos 是读取的开始位置,读取是 markpos - pos , marklimit最大的标记限制,不能超过pos的位置
2、BufferOutputStream
对于缓存输出流,其实也是一样,把JVM的buffer数据输出到操作系统内核空间(也是块传输)
private void ensureCapacity(int newcount) { if(newcount > this.buf.length) { byte[] newbuf = new byte[Math.max(this.buf.length << 1, newcount)]; System.arraycopy(this.buf, 0, newbuf, 0, this.count); //最后也是调用本地方法copy数据 this.buf = newbuf; } }
上面的方法是在ByteArrayBuffer里面
给出一段列子
try( BufferedInputStream bfi = new BufferedInputStream(new FileInputStream(new File("src"))); BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream(new File("dec")))){ int length = 0; for(;;){ if( (length = bfi.read()) !=-1){ bfo.write(length); }else break; } }catch (Exception e){ e.printStackTrace(); }