java输入输出流10_字节数组流

1.字节数组流概述

回顾我们所学的IO流,IO流按照处理对象不同来分类,可以分为节点流和包装流。目前我们所学的FileOutputStream、FileInputStream、FileWriter和FileReader都属于节点流,而缓冲流、转换流、打印流、数据流和对象流等都属于包装流。节点流都可以配合包装流来操作,例如直接使用字节流来复制文件效率低,那么我们可以使用缓冲流来提高效率。例如使用字节流来存取任意数据类型数据操作繁琐,那么我们可以使用对象流来简化操作等等。

接下来,我们要学习的字节数组流,它也属于节点流。字节数组流分为输入流和输出流,分别是:ByteArrayInputStream和ByteArrayOutputStream。使用字节数组流的时候,为了提高效率和简化操作,我们也可以让字节数组流配合包装流来一起使用。

常见的节点流中,例如:FileInputStreamr和FileReade都是把“文件”当做数据源,而ByteArrayInputStream则是把内存中的“字节数组”当做数据源。字节数组流,就是和内存中的数组相关的一个流,可以将字节数组写到输出流中,也可以将字节数组从输入流中读出来,不涉及磁盘。内存数组输出流可以看成一个可自动扩容的byte数组,可以往里写字节。

通过字节数组流,我们可以实现所有数据类型(基本数据类型、引用数据类型)和字节数组之间的转换,然后把转换成字节数组后可以保存到文件或者传输到网络。

2.ByteArrayOutputStream类

ByteArrayOutputStream字节数组输出流在内存中创建一个byte数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。缓冲区初始化时默认32个字节,会随着数据的不断写入而自动增长,但是缓冲区最大容量是2G,只要数据不超过2G,都可以往里写。

数据写出完毕后,可使用toByteArray()方法或toString()方法来获取数据,从而实现了将任意数据类型数据转化为字节数组。

例如,给一个字节数组,然后往这个数组中放入各种数据,比如整形、布尔型、浮点型、字符串和对象等,这种需求就可以使用ByteArrayOutputStream来实现。

【示例】将任意数据类型数据转化为字节数组案例

public class ArrayStreamTest {
	public static void main(String[] args) {
		try {
			// 字节数组输出流(节点流),可将任意数据类型转换为字节数组
			ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
			// 缓冲流(包装类),用于提高效率
			BufferedOutputStream bos = new BufferedOutputStream(baos);
			// 对象流(包装流),实现写出任意数据类型
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			// 使用对象流来写数据
			oos.writeInt(123);
			oos.writeDouble(123.45);
			oos.writeChar('A');
			oos.writeBoolean(false);
			oos.writeUTF("whsxt");
			oos.writeObject(new Date());
			// 刷新流,在获取数据之前一定要先刷新流,因为使用了包装流
			oos.flush();
			// 获取数据
			byte[] bs = baos.toByteArray();
			System.out.println(Arrays.toString(bs));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

通过查看底层源码,我们发现ByteArrayOutputStream类的close()方法并没有实现,所以调用close()方法关闭此流后仍可被使用。
在这里插入图片描述

3.ByteArrayInputStream类

字节数组输入流就是把一个字节数组 byte[] 包装了一下,使其具有流的属性,可顺序读下去,还可标记跳回来继续读,主要的作用就是用来读取字节数组中的数据。

同理,关闭ByteArrayInputStream无效,调用close()方法在关闭此流后仍可被调用。

【示例】读取上个案例获取的字符数组

public class ArrayStreamTest {
	public static void main(String[] args) {
		try {
			// 获取字节数组,返回上个案例中通过字节数组输出流写出的字节数组
			byte[] bs = outputStreamMethod();
			// 字节数组输入流(节点流),用于读取字节数组中的数据
			ByteArrayInputStream bios = new ByteArrayInputStream(bs);
			// 缓冲流(包装类),用于提高效率
			BufferedInputStream bis = new BufferedInputStream(bios);
			// 对象流(包装流),实现读取指定类型的数据
			ObjectInputStream ois = new ObjectInputStream(bis);
			// 读取数据
			System.out.println(ois.readInt());
			System.out.println(ois.readDouble());
			System.out.println(ois.readChar());
			System.out.println(ois.readBoolean());
			System.out.println(ois.readUTF());
			System.out.println(ois.readObject());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

补充,ByteArrayInputStream和ByteArrayOutputStream是字节数组流,那么与之对应的字符数组流则是StringReader和StringWriter。

与字节数组流相比,字符数组流反而用得更少,因为StringBuilder和StringBuffer也能方便的用来存储动态长度的字符,而且大家更熟悉这些类。

ps:如需最新的免费文档资料和教学视频,请添加QQ群(627407545)领取。

发布了92 篇原创文章 · 获赞 0 · 访问量 2607

猜你喜欢

转载自blog.csdn.net/zhoujunfeng121/article/details/104703599