• 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

  • 相关阅读:
    HTML元素解释
    Java命名规范
    HDU 1058 Humble Numbers(DP,数)
    HDU 2845 Beans(DP,最大不连续和)
    HDU 2830 Matrix Swapping II (DP,最大全1矩阵)
    HDU 2870 Largest Submatrix(DP)
    HDU 1421 搬寝室(DP)
    HDU 2844 Coins (组合背包)
    HDU 2577 How to Type(模拟)
    HDU 2159 FATE(二维完全背包)
  • 原文地址:https://www.cnblogs.com/brxHqs/p/13566453.html
Copyright © 2020-2023  润新知