黑马程序员——Java IO—字节流—ByteArrayInputStream和ByteArrayOutputStream
2014-10-01 16:36
656 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
ByteArrayInputStream 和 ByteArrayOutputStream
引用如下一段话来说明一下这2个类:
“内存虚拟文件或者内存映像文件就是把内存中的一块数据存储缓冲区,虚拟成一个文件,原来该写入硬盘文件上的内容可以被写入到这个内存中,原来该从硬盘文件中读取的内容也可以在内存中读取。而要在内存中定义一个大的内存缓冲区,这个内存缓冲区通常就是一个字节数组,在java中专门定义了这两个类用于以IO流的方式来完成对字节数组的读写来支持类似虚拟文件或者内存映像文件的类似功能。”
从这2个类的名字中就可以看出,它们和字节数组有关。
ByteArrayInputStream是一个输入流,既然是输入流,就应该有“输入源”。从ByteArrayInputStream的构造器中可以看到,它需要一个字节数组,这个被传入的字节数组将作为该输入流的源,也就是说调用read方法所读到的数据将是这个被传入的字节数组里的数据。
ByteArrayInputStream内部维护者一个byte数组,即调用构造方法时传入的数组,之后的所有操作都将建立在这个数组之上,并且该数组的大小不能改变(因为我们不需要向这个数组中写入数据,仅仅从里面都读取数据,所以没有必要改变它的大小)。
从ByteArrayInputStream的源码可以发现,它的close方法的方法体是空的,也就是在调用它的close方法后,依然可以从该输入流中读取数据(其实完全没必要关闭ByteArrayInputStream,因为它的内部根本就没有任何的流对象,所有被read方法返回的数据全部来自byte数组)。
ByteArrayOutputStream是一个输出流,既然是输出流,就应该有“目的地”。ByteArrayOutputStream的构造没有传入任何“目的地”,只有一个构造器传入一个名为size的int值。其实,ByteArrayOutputStream的“目的地”被封装在了其内部,也是一个byte数组,调用构造器时传入的size就是在指定内部数组的大小,默认的大小是32。当我们调用该类的write方法向目的地写入数据时,其实就是将数据写入该类内部的byte数组。
与ByteArrayInputStream中维护的byte数组不同的是,ByteArrayInputStream内部的数组的大小是不可变的,但是ByteArrayOutputStream内部的数组大小是可变的,当添加的数据的字节数比数组原来的长度大时,流内部会自动扩充内部数组的大小。
ByteArrayOutputStream提供了2个方法来获取内部数组的值:byte[] toByteArray() 和 String toString()。
toByteArray()在底层调用了Arrays.copyOf(byte[] buf, int newLength)来复制了内部byte数组的一个副本并返回,即返回后的数组与内部数组除了内容相同外没有任何关系。
同ByteArrayInputStream一样,ByteArrayOutputStream的close方法也是空实现,所以即使调用了它的close方法,也依然可以继续向它的内部数组中添加数据。
----------------------
ASP.Net
9f85
+Unity开发、.Net培训、期待与您交流! ----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
ByteArrayInputStream 和 ByteArrayOutputStream
引用如下一段话来说明一下这2个类:
“内存虚拟文件或者内存映像文件就是把内存中的一块数据存储缓冲区,虚拟成一个文件,原来该写入硬盘文件上的内容可以被写入到这个内存中,原来该从硬盘文件中读取的内容也可以在内存中读取。而要在内存中定义一个大的内存缓冲区,这个内存缓冲区通常就是一个字节数组,在java中专门定义了这两个类用于以IO流的方式来完成对字节数组的读写来支持类似虚拟文件或者内存映像文件的类似功能。”
从这2个类的名字中就可以看出,它们和字节数组有关。
ByteArrayInputStream是一个输入流,既然是输入流,就应该有“输入源”。从ByteArrayInputStream的构造器中可以看到,它需要一个字节数组,这个被传入的字节数组将作为该输入流的源,也就是说调用read方法所读到的数据将是这个被传入的字节数组里的数据。
ByteArrayInputStream内部维护者一个byte数组,即调用构造方法时传入的数组,之后的所有操作都将建立在这个数组之上,并且该数组的大小不能改变(因为我们不需要向这个数组中写入数据,仅仅从里面都读取数据,所以没有必要改变它的大小)。
从ByteArrayInputStream的源码可以发现,它的close方法的方法体是空的,也就是在调用它的close方法后,依然可以从该输入流中读取数据(其实完全没必要关闭ByteArrayInputStream,因为它的内部根本就没有任何的流对象,所有被read方法返回的数据全部来自byte数组)。
ByteArrayOutputStream是一个输出流,既然是输出流,就应该有“目的地”。ByteArrayOutputStream的构造没有传入任何“目的地”,只有一个构造器传入一个名为size的int值。其实,ByteArrayOutputStream的“目的地”被封装在了其内部,也是一个byte数组,调用构造器时传入的size就是在指定内部数组的大小,默认的大小是32。当我们调用该类的write方法向目的地写入数据时,其实就是将数据写入该类内部的byte数组。
与ByteArrayInputStream中维护的byte数组不同的是,ByteArrayInputStream内部的数组的大小是不可变的,但是ByteArrayOutputStream内部的数组大小是可变的,当添加的数据的字节数比数组原来的长度大时,流内部会自动扩充内部数组的大小。
ByteArrayOutputStream提供了2个方法来获取内部数组的值:byte[] toByteArray() 和 String toString()。
toByteArray()在底层调用了Arrays.copyOf(byte[] buf, int newLength)来复制了内部byte数组的一个副本并返回,即返回后的数组与内部数组除了内容相同外没有任何关系。
同ByteArrayInputStream一样,ByteArrayOutputStream的close方法也是空实现,所以即使调用了它的close方法,也依然可以继续向它的内部数组中添加数据。
package org.lgy.study.io; import java.io.*; /* javac -d classes "src/org/lgy/study/io/ByteArrayStreamTest.java" java org.lgy.study.io.ByteArrayStreamTest */ public class ByteArrayStreamTest{ public static void main(String[] args){ method1(); } public static void method1(){ try( // 其实没有必要关闭这2个流 ByteArrayInputStream bai = new ByteArrayInputStream("abcdefg".getBytes()); ByteArrayOutputStream bao = new ByteArrayOutputStream(); ) { int buf = 0; while((buf = bai.read()) != -1){ System.out.print((char)buf); bao.write(Character.toUpperCase((char)buf)); } System.out.println("\n" + bao.toString()); }catch(IOException e){ e.printStackTrace(); } } } /* 结果: abcdefg ABCDEFG */
package org.lgy.study.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.io.IOException; import java.util.Arrays; /* javac -d classes "src/org/lgy/study/io/test.java" java org.lgy.study.io.Test */ class Test{ public static void main(String[] args){ ByteArrayInputStream bai = null; ByteArrayOutputStream bao = null, bao2 = null; try{ // 使用平台默认的字符集 byte[] buf = "你好".getBytes(); System.out.println("\"你好\".getBytes() = " + Arrays.toString(buf)); // 使用指定的GBK字符集 byte[] gbkBuf = "你好".getBytes("GBK"); System.out.println("\"你好\".getBtyes(\"GBK\") = " + Arrays.toString(gbkBuf)); // 使用指定的UTF-8字符集 byte[] utfBuf = "你好".getBytes("UTF-8"); System.out.println("\"你好\".getBytes(\"UTF-8\") = " + Arrays.toString(utfBuf)); System.out.println(); // 利用指定的byte数组创建ByteArrayInputStream对象 bai = new ByteArrayInputStream(utfBuf); System.out.println("\"你好\".available() = " + bai.available() + "\n"); // 创建默认大小的ByteArrayOutputStream对象 bao = new ByteArrayOutputStream(); int i = 0; while((i = bai.read()) != -1){ bao.write(i); } // ByteArrayOutputStream的toByteArray()、toString()、toString(String charsetName) System.out.println("bao.toByteArray() = " + Arrays.toString(bao.toByteArray())); System.out.println("bao.toString() = " + bao.toString()); System.out.println("bao.toString(\"UTF-8\") = " + bao.toString("UTF-8") + "\n"); // writeTo(OutputStream out) bao2 = new ByteArrayOutputStream(); bao.writeTo(bao2); System.out.println("bao2.toByteArray() = " + Arrays.toString(bao2.toByteArray())); System.out.println("bao2.toString(\"UTF-8\") = " + bao2.toString("UTF-8") + "\n"); // size() System.out.println("bao2.size() = " + bao2.size() + "\n"); // reset() bao2.reset(); System.out.println("bao2.reset() = " + Arrays.toString(bao2.toByteArray())); }catch(UnsupportedEncodingException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); }finally{ try{ bai.close(); // ByteArrayInputStream的close方法是空实现。 }catch(IOException e){ e.printStackTrace(); } try{ bao.close(); // ByteArrayOutputStream的close方法是空实现。 }catch(IOException e){ e.printStackTrace(); } try{ bao2.close(); }catch(IOException e){ e.printStackTrace(); } } } } /* "你好".getBytes() = [-60, -29, -70, -61] "你好".getBtyes("GBK") = [-60, -29, -70, -61] "你好".getBytes("UTF-8") = [-28, -67, -96, -27, -91, -67] "你好".available() = 6 bao.toByteArray() = [-28, -67, -96, -27, -91, -67] bao.toString() = 浣犲ソ bao.toString("UTF-8") = 你好 bao2.toByteArray() = [-28, -67, -96, -27, -91, -67] bao2.toString("UTF-8") = 你好 bao2.size() = 6 bao2.reset() = [] */
----------------------
ASP.Net
9f85
+Unity开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- JAVA IO系列----ByteArrayInputStream和ByteArrayOutputStream类
- 转存:JAVA IO - ByteArrayInputStream和BufferedInputStream的区别
- Java IO - ByteArrayInputStream&ByteArrayOutputStream
- Java IO:ByteArrayInputStream使用详解及源码分析
- java.io ByteArrayInputStream与ByteArrayOutputStream理解(二)
- 黑马程序员——Java IO—字节流—ObjectInputStream和ObjectOutputStream
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- Java IO:常见Java IO流介绍(ByteArrayInputStream,ObjectInputStream,BufferedInputStream)
- java.io.ByteArrayInputStream的mark方法
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- java-(IO)之InputStream,FileInputStream,,Reader,PipedInputStream,ByteArrayInputStream
- Java_io体系之ByteArrayInputStream、ByteArrayOutputStream简介、走进源码及示例——04
- struts2下载文件时出现:java.lang.ClassCastException: java.io.ByteArrayInputStream cannot be cast to 错误
- Java之IO(三)ByteArrayInputStream和ByteArrayOutputStream
- struts2下载文件时出错提示:java.lang.ClassCastException: java.io.ByteArrayInputStream cannot be cast to java.l
- struts2下载文件时出现:java.lang.ClassCastException: java.io.ByteArrayInputStream cannot be cast to 错误
- Java IO之DataInputStream,ObjectInputStream,ByteArrayInputStream等
- 黑马程序员——Java IO—字节流—LineNumberInputStream
- Java IO 系列源码分析——ByteArrayInputStream和ByteArrayOutputStream
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)