个人好奇ByteArrayInputStream,到底是有什么用于是百度了一些资料 整合了下,
********这两个类对于要创建临时性文件的程序以及网络数据的传输、数据压缩后的传输等可以提高运行的的效率,可以不用访问磁盘。
同样有StringReader与StringWriter类以字符IO流的方式处理字符串。
流的来源或目的地并不一定是文件,也可以是内存中的一块空间,例如一个字节数组。java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream就是将字节数组当作流输入来源、输出目的地的类。
java.io.ByteArrayInputStream将一个字节数组当作流输入的来源,而java.io.ByteArrayOutputStream则可以将一个字节数组当作流输出目的地。
上面的程序就是把字符串转变为字节数组,并作为流输入的来源,用tranform()将字符串中所有的字母都转换为大写的,并将转换后的结果写到ByteArrayOutputStream中。
实例:
ByteArrayInputStream与ByteArrayOutputStream类用于以IO流的方式来完成对字节数组的内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
1
2 import java.io.*;
3
4 public class ByteArrayStreamTest {
5 public static void main(String [] args) {
6 String str = "abcdef";
7
8 ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes());
9 ByteArrayInputStream out = new ByteArrayOutputStream();
10
11 transform(in, out);
12
13 byte[] result = out.toByteArray();
14
15 System.out.println(out);
16 System.out.println(new String(result));
17
18 transform(System.in, System.out); // 从键盘读,输出到显示器
19 }
20
21 public static void transform(InputStream in, OutputStream out) {
22 int ch = 0;
23
24 try {
25 while ((ch = in.read()) != -1) {
26 int upperChar = Character.toUpperCase((char)ch);
27 out.write(upperChar);
28 } // close while
29 } catch (Exception e) {
30 e.printStackTrace();
31 }
32 }
33 }
有时候我们需要对同一个InputStream对象使用多次。比如,客户端从服务器获取数据 ,利用HttpURLConnection的getInputStream()方法获得Stream对象,这时既要把数据显示到前台(第一次读取),又想把数据写进文件缓存到本地(第二次读取)。
但第一次读取InputStream对象后,第二次再读取时可能已经到Stream的结尾了(EOFException)或者Stream已经close掉了。
而InputStream对象本身不能复制,因为它没有实现Cloneable接口。此时,可以先把InputStream转化成ByteArrayOutputStream,后面要使用InputStream对象时,再从ByteArrayOutputStream转化回来就好了。代码实现如下:
1
2
3
4 InputStream input = httpconn.getInputStream();
5
6 ByteArrayOutputStream baos = new ByteArrayOutputStream();
7 byte[] buffer = new byte[1024];
8 int len;
9 while ((len = input.read(buffer)) > -1 ) {
10 baos.write(buffer, 0, len);
11 }
12 baos.flush();
13
14
15 InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());
16
17
18 //TODO:显示到前台
19
20
21 InputStream stream2 = new ByteArrayInputStream(baos.toByteArray());
22
23
24 //TODO:本地缓存
BufferedOutputStream 和 ByteArrayOutputStream的区别
BufferedOutputStream是一个缓冲数据输出流接口, ByteArrayOutputStream则是字节数组输出流接口. 这2个输出流都是我们经常用到的, 它们都是OutputStream的子类,而什么时候选择用它们呢, 这个就要看你运用到什么应用场景下了.
下来先来看下源码吧.
1.BufferedOutputStream会首先创建一个默认的容器量, capacity = 8192 = 8KB,
每次在写的时候都会去比对capacity是否还够用, 如果不够用的时候, 就flushBuffer(),
把buf中的数据写入对应的outputStream中, 然后将buf清空, 一直这样等到把内容写完. 在这过程中主要起到了一个数据缓冲的功能.
1 public synchronized void write(byte b[], int off, int len) throws IOException {
2 // 在这判断需要写的数据长度是否已经超出容器的长度了,如果超出则直接写到相应的outputStream中,并清空缓冲区
3 if (len >= buf.length) {
4 flushBuffer();
5 out.write(b, off, len);
6 return;
7 }
8 // 判断缓冲区剩余的容量是否还够写入当前len的内容,如果不够则清空缓冲区
9 if (len > buf.length - count) {
10 flushBuffer();
11 }
12 // 将要写的数据先放入内存中,等待数据达到了缓冲区的长度后,再写到相应的outputStream中
13 System.arraycopy(b, off, buf, count, len);
14 count += len;
15 }
flushBuffer () 这个方法干了些什么呢, 来看看源码
1 private void flushBuffer() throws IOException {
2 if (count > 0) {
3 // 把写入内存中的数据写到构造方法里传入的OutputStream句柄里, 并把容量大小清楚
4 out.write(buf, 0, count);
5 count = 0;
6 }
7 }
这个类最重要的就是这2个方法, 这样节省了大量的内存空间, 合理的分配内存来完成数据输出,当你资源不是那么充沛时, 选择这个类来实现你想要的东西是不是很合适呢?
2.普通的OutputStream, 例如ByteArrayOutputStream也会首先创建一个默认的容器量, capacity = 32 =
32b, 每次在写的时候都会去比对capacity是否还够用, 如果不够用的时候, 就重新创建buf的容量, 一直等到内容写完,
这些数据都会一直处于内存中.
1 public synchronized void write(byte b[], int off, int len) {
2 if ((off < 0) || (off > b.length) || (len < 0) ||
3 ((off + len) > b.length) || ((off + len) < 0)) {
4 throw new IndexOutOfBoundsException();
5 } else if (len == 0) {
6 return;
7 }
8 // 不断对自己的容量进行相加
9 int newcount = count + len;
10 // 如果新的容量大小已经超过了现有的大小时,则重新开辟新的内存区域来保存当前的数据
11 if (newcount > buf.length) {
12 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
13 }
14 System.arraycopy(b, off, buf, count, len);
15 count = newcount;
16 }
总结 : 当你资源不足够用时,选择BufferedOutputStream是最佳的选择, 当你选择快速完成一个作业时,可以选择ByteArrayOutputStream之类的输出流
转自:http://blog.csdn.net/huijie618/article/details/50233081