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
ByteArrayInputStream的作用,和BufferedOutputStream 的区别的更多相关文章
- apache的作用和tomcat的区别
经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料,总 ...
- gets,fgets,puts,fputs,scanf,printf的作用,联系和区别
转载: https://blog.csdn.net/lc10915819/article/details/12747943
- Android Parcelable和Serializable的区别,androidparcelable
本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...
- JS中offsetLeft,Left,clientLeft的区别(纯转贴)
假设 obj 为某个 HTML 控件. obj.offsetTop 指 obj 相对于版面或由 offsetParent 属性指定的父坐标的计算上侧位置,整型,单位像素. obj.offsetLeft ...
- JAVA多线程suspend()、resume()和wait()、notify()的区别
suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态.典型 ...
- Android Parcelable和Serializable的区别
本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...
- 线程的状态有哪些,线程中的start与run方法的区别
线程在一定条件下,状态会发生变化.线程一共有以下几种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法. ...
- [转]Android Parcelable和Serializable的区别
本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...
- java线程状态 以及 sheep()、wait()、yield() 区别
前言 最近看到很多人都在讨论多线程的问题,于是写出了这篇博客,希望可以帮到正在学习和使用这块的朋友们,首先我们先看看两个图(两个图都来自其他码农的分享) 这两个图是一样的逻辑,这里一起罗列出来,下 ...
随机推荐
- javase(4)_数组
一.数组概述 数组可以看成是多个相同类型数据组合,对这些数据的统一管理. 数组变量属于引用类型,数组也可以看成对象,数组中的每个元素相当于该对象的成员变量. 数组中的元素可以是任意类型,包括基本类型和 ...
- 三. python面向对象
第七章.面向对象基础 1.面向对象基础 类和对象: a. 创建类 class 类名: def 方法名(self,xxx): pass b. 创建对象 对象 = 类名() c. 通过对象执行方法 对象. ...
- Spring根据XML配置文件注入属性 其实也是造bean,看看是使用constructor还是setter顺带完成属性赋值
方法一使用setter方法 package com.swift; public class Book { private String bookName; public void setBook(St ...
- Python 列表相关
python列表 列表推导式 例1 [ i*i for i in range(10) ] 打印如下: >>> [i*i for i in range(10)] [0, 1, 4, 9 ...
- Day07 数据类型(列表,元组,字典,集合)常用操作和内置方法
数据类型 列表list: 用途:记录多个值(同种属性) 定义方式:[]用逗号分隔开多个任意类型的值 list()造出来的是列表,参数是可迭代对像,也就是可以使用for循环的对像 传入字典,出来的列表元 ...
- 入门人工智能的首选语言为什么会是Python?
为何人工智能(AI)首选Python?当你读完这篇文章就会明白了.为何人工智能(AI)首选Python?读完这篇文章你就知道了.我们看谷歌的TensorFlow基本上所有的代码都是C++和Python ...
- 零基础学Python不迷茫——基本学习路线及教程!
什么是Python? 在过去的2018年里,Python成功的证明了它自己有多火,它那“简洁”与明了的语言成功的吸引了大批程序员与大数据应用这的注意,的确,它的实用性的确是配的上它的热度. Pyt ...
- Ajax四步操作
第一步得到(XMLHttpRequest)function creatXMLHttpRequest(){ try{ return new XMLHttpRequest(); } catch(e){ t ...
- LeetCode(137) Single Number II
题目 Given an array of integers, every element appears three times except for one. Find that single on ...
- HDU 4003 Find Metal Mineral
这个题是POJ1849的加强版. 先说一个很重要的结论,下面两种方法都是从这个结论出发的. 一个人从起点遍历一颗树,如果最终要回到起点,走过的最小权值就是整棵树的权值的2倍. 而且K个人的情况也是如此 ...