这两个流是带有缓存功能的流(一般读取文件都建议用这两个)
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();
}
本文详细介绍了Java中BufferedInputStream和BufferedOutputStream的工作原理。通过分析fill()方法,揭示了带有缓存功能的输入流如何减少磁盘I/O操作,提高读取效率。同时,也解释了缓存输出流如何实现数据的高效写入。
1671

被折叠的 条评论
为什么被折叠?



