JavaIO流中几个特殊封装的流

上面两篇博客主要总结了一下IO流的基础字节流和字符流,这篇总结一下几个特殊的封装流。

SequenceInputStream
序列流
序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时,
将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.

将多个字节流整合成一个:

public class Demo01 {
	public static void main(String[] args) throws Exception {
		//SequenceInputStream序列流使用二
		//需求,把a.txt b.txt c.txt 的内容拷贝到d.txt
		//1.Vector是集合  区别于arrylist 它是线程安全的
		Vector<InputStream> vector = new Vector<InputStream>();
		vector.add(new FileInputStream("a.txt"));
		vector.add(new FileInputStream("b.txt"));
		vector.add(new FileInputStream("c.txt"));
		//2.Enumeration枚举
		Enumeration<InputStream> e = vector.elements();
		//3.序列流
		SequenceInputStream sis = new SequenceInputStream(e);
		//4.创建输出流
		FileOutputStream fos = new FileOutputStream("d.txt");
		//读写 
		int b = 0;
		while((b = sis.read()) != -1){
			fos.write(b);
		}
		
		sis.close();
		fos.close();
	}
}

ByteArrayOutputStream
字节数组输出流
ByteArrayOutputStream 字节数组输出流
ByteArrayOutputStream 不需要关联文件 只是写入内存。
此类实现了一个输出流,其中的数据被写入一个 byte 数组 缓冲区。
缓冲区会随着数据的不断写入而自动增长。
可使用 toByteArray() 和 toString() 获取数据。
在这里插入图片描述ByteArrayOutputStream的使用

        //1.创建字节数组输出流对象
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		//2.输入流
		FileInputStream fis = new FileInputStream("a.txt");
		//3.写入输出流
		int b = 0;
		while((b = fis.read()) != -1){
			baos.write(b);
		}
		//自动把字节数组 转成 字符串
		System.out.println(baos.toString());
		System.out.println(baos.toString("UTF-8"));//指定编码格式的字符串
		
		//获取文件数据
		byte[] bytes = baos.toByteArray();
		System.out.println(new String(bytes));
		System.out.println(new String(bytes, "UTF-8"));//指定编码格式的字符串
		//4.关流
		fis.close();

对象操作流
1ObjectInputStream
这个类是从文件中读取对象

2 ObjectOutputStream
这个类是将一个对象写入文件
如果使用这个类写入对象,这个对象需要序列化
ps:
序列化就是让这个对象实现一个Serializable接口
如果没实现Serializable接口,会抛异常NotSerializableException
对象写入文件时,乱码没有关系,取出来正确就行了

序列化相关概念
归档(序列化) :将对象存在一个文件的过程
解归档(反序列化):把一个文件解析出对象
Serializable接口的ID讲解
1.要归档或者序列化的对象必须实现Serializable接口才能被序列化
2.Serializable 中有个id,但ID不是一定要加的
3.SerialVersionUid,简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
4.如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。
5.如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;
6.如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。
7.一般不会添加ID,就算添加了ID,版本号最好不要修改

ublic class 对象操作流 {

	public static void main(String[] args) {
		// 这里使用一下Vector
		Vector<car> cars = new Vector<car>();
		cars.add(new car("宝马", 1000));
		cars.add(new car("奔驰", 100));
		cars.add(new car("大众", 10000));
		try (OutputStream outputStream = new FileOutputStream("a.data");
				InputStream inputStream = new FileInputStream("a.data");
				ObjectOutput objectOutput = new ObjectOutputStream(outputStream);
				ObjectInput objectInput = new ObjectInputStream(inputStream);) {
			objectOutput.writeObject(cars);
			Vector<car> cars2 = (Vector<car>) objectInput.readObject();
			
			//转成枚举
			Enumeration<car> enumeration = cars.elements();
			//遍历枚举
			for(Enumeration e=enumeration;e.hasMoreElements();)
			{
				System.out.println(e.nextElement());
			}
			
		   
			

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

}

class car implements Serializable {

	private String name;
	private int price;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public car(String name, int price) {
		this.name = name;
		this.price = price;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "car: [ name:" + name + " price:" + price + " ]";
	}
}

打印流
PrintStream 打印字节流
System.out就是一个PrintStream, 其默认向控制台输出信息
该流可以很方便的将对象的toString()结果输出, 并且自动加上换行
PrintWriter 打印字符流
这个流是向文件打印信息,也就是将打印的内容写入文件

//1.打印的字节流【打印到控制台】
		PrintStream ps = System.out;
		ps.println("你好,元宵节快乐");//打印字符串
		ps.println(19.6);
		
		//2.打印的字符流
		/**
		 * 1.PrintWriter调用打印方法,控制台是没有内容,它是把内容写到文件中
		 * 2.如果打印了内容,没有调用flush或者close,内容在文件中也不存在
		 */
		PrintWriter pw = new PrintWriter("test.txt");
		pw.println("吃汤圆了...");
		pw.print("超市一包汤圆10几块钱");
		pw.print(13.01);
		//pw.flush();
		pw.close();

标准输入输出流
System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据
System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据

随机访问流
RandomAccessFile类不属于流,是Object类的子类。
但它融合了InputStream和OutputStream的功能。
支持对随机访问文件的读取和写入。

/**
		 * 构造方法两个参数:
		 * name:文件名称、路径
		 * mode:模式 ,r=read 只读、 w=write
		 */
		//1.创建一个随机访问流对象,以读写的方式打开文件
		RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
		
		//2.读字符
		/**
		 * 使用RandomAccessFile的readChar/readLine方法读文件有乱码问题
		 */
/*		System.out.println(raf.readChar());
		System.out.println(raf.readChar());
		System.out.println(raf.readChar());
		System.out.println(raf.readLine());*/
		
		//使用字节数组来读比较好
/*		byte[] buf = new byte[1024];
		int len;
		while((len = raf.read(buf)) != -1){
			System.out.println(new String(buf,0,len));
		}*/
		
		//3.写数据
		//raf.writeChars("abc");
		//raf.writeBytes("abc");
		raf.seek(4);//指定位置
		raf.write(97);
		raf.write(98);
		raf.write(99);
	}

数据输入输出流
DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
例如按Long大小写出一个数字, 写出时该数据占8字节.
读取的时候也可以按照Long类型读取, 一次读取8个字节.

	long a = 997;
	long b = 998;
	long c = 999;
		
		//使用FileOutputStream没法写入long类型数据
		FileOutputStream fos = new FileOutputStream("a.txt");
		//byte -128~127 0~255
/*		fos.write(997);只会写一个字节,不会写8个字节
		fos.write(998);
		fos.write(999);*/
		
		//fos.wr
		DataOutputStream dos = new DataOutputStream(fos);
		dos.writeLong(a);//写8个字节
		dos.writeLong(b);
		dos.writeLong(c);
		
		dos.close();

		//读3个long数据
		DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
		System.out.println(dis.readLong());//读8个字节
		System.out.println(dis.readLong());//读8个字节
		System.out.println(dis.readLong());//读8个字节

Properties类【掌握-经常用】
Properties:属性,与Map的使用有点类似
Properties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载,这个类可以读写文件。
属性列表中每个键及其对应值都是一个字符串。
存中文时,会转成Unicode编译存储

// 声明对象
		Properties properties = new Properties();
		// 设置键值对
		properties.setProperty("名字", "林大哥");
		properties.setProperty("密码", "123");
		try {
			// 写入 
			properties.store(new FileWriter("a.properties"), null);
			// 读取
			properties.load(new FileReader("a.properties"));
			// 遍历一
			// 获取所有的键
			Set<Object> set = properties.keySet();
			for (Object key : set) {
				System.out.println(key + ":" + properties.get(key));
			}
			System.out.println(".............");
			// 遍历二
			for (Entry<Object, Object> entry : properties.entrySet()) {
				System.out.println(entry.getKey() + ":" + entry.getValue());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
发布了23 篇原创文章 · 获赞 17 · 访问量 1282

猜你喜欢

转载自blog.csdn.net/qq_41587409/article/details/105397866