• ByteArrayInputStream的作用,和BufferedOutputStream 的区别


    个人好奇ByteArrayInputStream,到底是有什么用于是百度了一些资料 整合了下,
    ********这两个类对于要创建临时性文件的程序以及网络数据的传输、数据压缩后的传输等可以提高运行的的效率,可以不用访问磁盘。
    同样有StringReader与StringWriter类以字符IO流的方式处理字符串。
    流的来源或目的地并不一定是文件,也可以是内存中的一块空间,例如一个字节数组。java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream就是将字节数组当作流输入来源、输出目的地的类
    java.io.ByteArrayInputStream将一个字节数组当作流输入的来源,而java.io.ByteArrayOutputStream则可以将一个字节数组当作流输出目的地。
    上面的程序就是把字符串转变为字节数组,并作为流输入的来源,用tranform()将字符串中所有的字母都转换为大写的,并将转换后的结果写到ByteArrayOutputStream中。
    实例:
    ByteArrayInputStream与ByteArrayOutputStream类用于以IO流的方式来完成对字节数组的内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。

     

    import java.io.*;

    public class ByteArrayStreamTest {
    public static void main(String [] args) {
    String str = "abcdef";

    ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes());
    ByteArrayInputStream out = new ByteArrayOutputStream();

    transform(in, out);

    byte[] result = out.toByteArray();

    System.out.println(out);
    System.out.println(new String(result));

    transform(System.in, System.out); // 从键盘读,输出到显示器
    }

    public static void transform(InputStream in, OutputStream out) {
    int ch = 0;

    try {
    while ((ch = in.read()) != -1) {
    int upperChar = Character.toUpperCase((char)ch);
    out.write(upperChar);
    } // close while
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    有时候我们需要对同一个InputStream对象使用多次。比如,客户端从服务器获取数据 ,利用HttpURLConnection的getInputStream()方法获得Stream对象,这时既要把数据显示到前台(第一次读取),又想把数据写进文件缓存到本地(第二次读取)。
    但第一次读取InputStream对象后,第二次再读取时可能已经到Stream的结尾了(EOFException)或者Stream已经close掉了。
    而InputStream对象本身不能复制,因为它没有实现Cloneable接口。此时,可以先把InputStream转化成ByteArrayOutputStream,后面要使用InputStream对象时,再从ByteArrayOutputStream转化回来就好了。代码实现如下:

     

    InputStream input = httpconn.getInputStream();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = input.read(buffer)) > -1 ) {
    baos.write(buffer, 0, len);
    }
    baos.flush();


    InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());


    //TODO:显示到前台


    InputStream stream2 = new ByteArrayInputStream(baos.toByteArray());


    //TODO:本地缓存


    BufferedOutputStream 和 ByteArrayOutputStream的区别

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

    1.BufferedOutputStream会首先创建一个默认的容器量, capacity = 8192 = 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;
    }


    flushBuffer () 这个方法干了些什么呢, 来看看源码 

     

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

    这个类最重要的就是这2个方法, 这样节省了大量的内存空间, 合理的分配内存来完成数据输出,当你资源不是那么充沛时, 选择这个类来实现你想要的东西是不是很合适呢?
    2.普通的OutputStream, 例如ByteArrayOutputStream也会首先创建一个默认的容器量, capacity = 32 = 32b, 每次在写的时候都会去比对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之类的输出流

    转自:http://blog.csdn.net/huijie618/article/details/50233081

  • 相关阅读:
    electron 持续获取程序运行时间
    nfc reader iso7816 读卡器参考资料
    vue项目
    【数学】充分必要条件
    .Net 【DevExpress】 GridControl常用功能
    .Net 【基础回顾】关键字补充default
    .Net 【工作应用】 Ado.net总结
    .Net 【DevExpress】 MemoEdit总结
    发送短信封装
    Codeforces 1666 Labyrinth
  • 原文地址:https://www.cnblogs.com/renjiaqi/p/11411931.html
Copyright © 2020-2023  润新知