zoukankan      html  css  js  c++  java
  • BufferedOutputStream和ByteArrayOutputStream区别

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

    1.BufferedOutputStream实现原理:

    tip:BufferedOutputStream 默认是new byte[8192]字节,ByteArrayOutputStream默认是new byte[32]字节

    BufferedOutputStream会首先创建一个默认的容器量, capacity = 8192B = 8KB, 每次在写的时候都会去比对capacity是否还够用, 如果不够用的时候, 就flushBuffer(), 把buf中的数据写入对应的outputStream中, 然后将buf清空, 一直这样等到把内容写完. 在这过程中主要起到了一个数据缓冲的功能. 

    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;  
        }  
    private void flushBuffer() throws IOException {  
           if (count > 0) {  
              // 把写入内存中的数据写到构造方法里传入的OutputStream句柄里, 并把容量大小清楚  
        out.write(buf, 0, count);  
        count = 0;  
           }  
       }  

    2.ByteArrayOutputStream实现原理:

    也会首先创建一个默认的容器量, capacity = 32 = 32byte, 每次在写的时候都会去比对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;  
        }  
    

     

    应用:

    public static <T extends Serializable> T clone(T obj) throws Exception {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
        //个人感觉用Buffered系列,还需要传入一个指定容器,比如文件对应的写出流,相比,ByteArray临时处理一些小数据,很方便,数据直接全量存储在内存中(基于内存的流),
        //获取内存中的数据,直接toByteArray()即可 ObjectOutputStream oos
    = new ObjectOutputStream(bout); oos.writeObject(obj);//将obj流数据写入内存 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bin); return (T) ois.readObject(); // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义 // 基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放 }

     转https://www.iteye.com/blog/z276356445t-1955400

  • 相关阅读:
    django rest_framework中将json输出字符强制为utf-8编码
    Java
    Java
    Oracle
    IDEA
    Ubuntu
    Ubuntu
    Ubuntu
    Ubuntu
    Oracle
  • 原文地址:https://www.cnblogs.com/brxHqs/p/13566453.html
Copyright © 2011-2022 走看看