Java源码剖析之InputStream与OutputStream(1) --- BufferedOutputStream和普通ByteArrayOutputS_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java源码剖析之InputStream与OutputStream(1) --- BufferedOutputStream和普通ByteArrayOutputS

Java源码剖析之InputStream与OutputStream(1) --- BufferedOutputStream和普通ByteArrayOutputS

 2013/10/11 18:21:30  z276356445t  程序员俱乐部  我要评论(0)
  • 摘要:又是好久没写博客了,今天也心血来潮,把以前的笔记整理了一下,一点点发出来.今天主要是想记录下BufferedOutputStream和ByteArrayOutputStream区别众所周知BufferedOutputStream是一个缓冲数据输出流接口,ByteArrayOutputStream则是字节数组输出流接口.这2个输出流都是我们经常用到的,它们都是OutputStream的子类,而什么时候选择用它们呢,这个就要看你运用到什么应用场景下了.下来先来看下源码吧.1
  • 标签:源码 Java
又是好久没写博客了, 今天也心血来潮, 把以前的笔记整理了一下, 一点点发出来.

今天主要是想记录下BufferedOutputStream和ByteArrayOutputStream区别

众所周知BufferedOutputStream是一个缓冲数据输出流接口, ByteArrayOutputStream则是字节数组输出流接口. 这2个输出流都是我们经常用到的, 它们都是OutputStream的子类,而什么时候选择用它们呢, 这个就要看你运用到什么应用场景下了.

下来先来看下源码吧.

1.BufferedOutputStream会首先创建一个默认的容器量, capacity = 8192 = 8KB, 每次在写的时候都会去比对capacity是否还够用, 如果不够用的时候, 就flushBuffer(), 把buf中的数据写入对应的outputStream中, 然后将buf清空, 一直这样等到把内容写完. 在这过程中主要起到了一个数据缓冲的功能.
class="java" name="code">
public synchronized void write(byte b[], int off, int len) throws IOException {
      // 在这判断需要写的数据长度是否已经超出容器的长度了,如果超出则直接写到相应的outputStream中,并清空缓冲区
      if (len >= buf.length) {
          flushBuffer();
          out.write(b, off, len);
          return;
      }
      // 判断缓冲区剩余的容量是否还够写入当前len的内容,如果不够则清空缓冲区
      if (len > buf.length - count) {
          flushBuffer();
      }
      // 将要写的数据先放入内存中,等待数据达到了缓冲区的长度后,再写到相应的outputStream中
      System.arraycopy(b, off, buf, count, len);
      count += len;
    }



flushBuffer () 这个方法干了些什么呢, 来看看源码
 private void flushBuffer() throws IOException {
        if (count > 0) {
           // 把写入内存中的数据写到构造方法里传入的OutputStream句柄里, 并把容量大小清楚
	    out.write(buf, 0, count);
	    count = 0;
        }
    }


这个类最重要的就是这2个方法, 这样节省了大量的内存空间, 合理的分配内存来完成数据输出,当你资源不是那么充沛时, 选择这个类来实现你想要的东西是不是很合适呢?

2.普通的OutputStream, 例如ByteArrayOutputStream也会首先创建一个默认的容器量, capacity = 32 = 32KB, 每次在写的时候都会去比对capacity是否还够用, 如果不够用的时候, 就重新创建buf的容量, 一直等到内容写完, 这些数据都会一直处于内存中.
public synchronized void write(byte b[], int off, int len) {
      if ((off < 0) || (off > b.length) || (len < 0) ||
            ((off + len) > b.length) || ((off + len) < 0)) {
          throw new IndexOutOfBoundsException();
      } else if (len == 0) {
          return;
      }
        // 不断对自己的容量进行相加
        int newcount = count + len;
        // 如果新的容量大小已经超过了现有的大小时,则重新开辟新的内存区域来保存当前的数据
        if (newcount > buf.length) {
            buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
        }
        System.arraycopy(b, off, buf, count, len);
        count = newcount;
    }


注释中已经对这个类进行了详细的解释

总结 : 当你资源不足够用时,选择BufferedOutputStream是最佳的选择, 当你选择快速完成一个作业时,可以选择ByteArrayOutputStream之类的输出流
发表评论
用户名: 匿名