学习JavaEE的日子 Day37 各种流

本文详细介绍了Java中的对象流(包括ObjectInputStream和ObjectOutputStream)、序列化与反序列化过程,以及内存流(ByteArrayInputStream和ByteArrayOutputStream)的使用。此外,还涵盖了PrintStream和PrintWriter的区别,以及如何重定向系统输入输出流和使用RandomAccessFile进行文件操作,最后解释了Java序列化的概念和实现方法。
摘要由CSDN通过智能技术生成

各种流

1.对象流

class ObjectInputStream – 对象输入流

class ObjectOutputStream – 对象输出流

理解:

​ 将程序中的对象写入到文件

​ 并且从文件中读取出对象到程序里

序列化(钝化):将程序里的对象写入到文件

反序列化(活化):将文件里的对象读取到程序中

注意:

  1. 如果对象想写入文件,对象所属的类就必须实现序列化接口(Serializable)
  2. Serializable序列化接口没有任何的属性和方法,这种接口称之为标记型接口
  3. 对象所属的类实现了序列化接口一定要添加序列化ID(serialVersionUID)
  4. 属性使用transient修饰,该属性不会随着对象而写入到文件中
1.1 利用对象输出流 向文件写入数据ObjectOutputStream
public class Test01 {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		
		//1.创建流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
		
		//2.写入数据
		oos.writeInt(100);//写入int值
		oos.writeDouble(123.123);//写入double值
		oos.writeUTF("用良心做教育");//写入字符串
		oos.writeObject(new Date());//写入对象
		
		//3.关闭资源
		oos.close();
	}
}
1.2 利用对象输入流 读取文件里的数据ObjectInputStream
public class Test02 {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		//1.创建流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
		
		//2.读取数据(读取顺序必须和写入顺序一致)
		int readInt = ois.readInt();
		double readDouble = ois.readDouble();
		String str = ois.readUTF();
		Date date = (Date) ois.readObject();
		
		System.out.println(readInt);
		System.out.println(readDouble);
		System.out.println(str);
		System.out.println(date);
		
		//3.关闭资源
		ois.close();
		
	}
}
1.3 利用对象输出流 向文件写入自定义对象ObjectOutputStream
public class Test03 {
	/**
	 * 知识点:利用对象输出流 向文件写入自定义对象
	 */
	public static void main(String[] args) throws FileNotFoundException, IOException {
		
		//1.创建流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
		
		//2.写入自定义对象
		oos.writeObject(new User("1445584980", "123123"));
		oos.writeObject(new User("1534534534", "111222"));
		oos.writeObject(new User("5345356683", "123456"));
		oos.writeObject(null);
		
		//3.关闭资源
		oos.close();
		
	}
}

User类

public class User implements Serializable{//要实现序列化接口(Serializable)
	
	private static final long serialVersionUID = 4907921883130742331L;
	
	private String username;
	private transient String password;
	
    //无参构造,有参构造,get,set方法省略
1.4 利用对象输入流 读取文件中的自定义对象ObjectInputStream
public class Test04 {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		//1.创建流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
		
		//2.读取自定义对象
		User user;
		while((user = (User)ois.readObject()) != null){
			System.out.println(user);
		}
		
		//3.关闭资源
		ois.close();
	}
}

2.内存流

class ByteArrayInputStream – 内存输入流

class ByteArrayOutputStream – 内存输出流

注意:

  1. 内存流是程序和内存交互,跟文件无关
  2. 内存流是程序到内存的通道,是关闭不掉的

应用场景:项目中频繁使用的数据可以使用内存流备份一份

2.1 内存输出流ByteArrayOutputStream
public class Test01 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		//关闭资源(内存流是程序到内存的通道,是关闭不掉的)
		//baos.close();
		
		//2.写入数据 -- 将数据写入到baos对象中的byte数组里
		baos.write("123abc木头人".getBytes());
		
		//获取流对象里的数据
		System.out.println(new String(baos.toByteArray()));
		System.out.println(baos.toString());
	}
}
2.2 内存输入流ByteArrayInputStream
public class Test02 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		ByteArrayInputStream bais = new ByteArrayInputStream("123abc木头人".getBytes());
		
		//关闭资源(内存流是程序到内存的通道,是关闭不掉的)
		//bais.close();
		
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = bais.read(bs)) != -1){
			System.out.println(new String(bs, 0,len));
		}		
		
	}
}

3.打印流

class PrintStream – 字节打印流

class PrintWriter – 字符打印流

注意:打印流实际上就是输出流,只有一个方向(程序->文件)

PrintStream vs PrintWriter

区别1:PrintStream是以字节为单位,PrintWriter是以字符为单位

区别2:

​ PrintStream:将字节流转换为字节打印流

​ PrintWriter:将字节流和字符流转换为字符打印流

3.1 字节打印流PrintStream
public class Test01 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		//PrintStream ps = new PrintStream("io.txt");
		
		//1.创建流对象(字节流 -> 字节打印流)
		//PrintStream ps = new PrintStream(new FileOutputStream("io.txt"));
		
		//1.创建流对象(字节流 -> 字节打印流) + 在末尾追加
		PrintStream ps = new PrintStream(new FileOutputStream("io.txt",true));
		
		//2.写入数据
		ps.write("好好学习".getBytes());
		
		//3.关闭资源
		ps.close();		
		
	}
}
3.2 字符打印流PrintWriter
public class Test02 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		//PrintWriter pw = new PrintWriter("io.txt");
		
		//1.创建流对象(字节流 -> 字节打印流)
		//PrintWriter pw = new PrintWriter(new FileOutputStream("io.txt"));
		
		//1.创建流对象(字节流 -> 字节打印流) + 在末尾追加
		//PrintWriter pw = new PrintWriter(new FileOutputStream("io.txt",true));
		
		//1.创建流对象(字符流 -> 字符打印流)
		//PrintWriter pw = new PrintWriter(new FileWriter("io.txt"));
		
		//1.创建流对象(字符流 -> 字符打印流) + 在末尾追加
		//PrintWriter pw = new PrintWriter(new FileWriter("io.txt",true));
		
		//1.创建流对象(设置编码格式 + 在末尾追加 + 考虑到效率)
		PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("io.txt",true), "GBK")));
		
		//2.写入数据
		pw.write("好好学习");
		
		//3.关闭资源
		pw.close();		
		
	}
}

4.扩展:重定向

理解:重新定义系统标准的输入流、输出流、错误输出流的方向

System.in:获取系统标准输入流的方向(控制台->程序)
System.out:获取系统标准输出流的方向(程序->控制台)
System.err:获取系统标准错误输出流的方向(程序->控制台)

//重定向:重新定义系统标准输入流的方向(文件->程序)
System.setIn(new FileInputStream(“io.txt”));

//重定向:重新定义系统标准输出流的方向(程序->文件)
System.setOut(new PrintStream(new FileOutputStream(“io.txt”,true)));

//重定向:重新定义系统标准错误输出流的方向(程序->文件)
System.setErr(new PrintStream(new FileOutputStream(“io.txt”,true)));

4.1 System.in
public class Test03 {
	public static void main(String[] args) throws FileNotFoundException {
		
		//重定向:重新定义系统标准输入流的方向(文件->程序)
		System.setIn(new FileInputStream("io.txt"));
		
		InputStream in = System.in;
		
		Scanner scan = new Scanner(in);
		String str = scan.next();
		System.out.println(str);
		scan.close();
	}
	
}
4.2 System.out
public class Test04 {
	public static void main(String[] args) throws FileNotFoundException {
		
		//重定向:重新定义系统标准输出流的方向(程序->文件)
		System.setOut(new PrintStream(new FileOutputStream("io.txt",true)));
		
		PrintStream ps = System.out;
		ps.println("好好学习");
	}
	
}
4.3 System.err
public class Test05 {
	public static void main(String[] args) throws FileNotFoundException {
		
		//重定向:重新定义系统标准错误输出流的方向(程序->文件)
		System.setErr(new PrintStream(new FileOutputStream("io.txt",true)));
		
		PrintStream ps = System.err;
		ps.println("好好学习");
	}
	
}

5.随机访问流

class RandomAccessFile

理解:该流认为文件是一个大型的byte数组。有一个隐藏的指针(默认为0),其实就是下标,可以从指针的位置写入或读取,意味着该流两个方向

模式:r-读,rw-读写

5.1 利用随机访问流 向文件写入数据 RandomAccessFile

需求1:向文件写入 数字、英文、中文数据

public class Test01 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile w = new RandomAccessFile("io.txt", "rw");
		
		//2.写入数据
		w.write("123abc木头人".getBytes());
		
		//3.关闭资源
		w.close();
	}
}

需求2:在文件末尾追加

public class Test02 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		File file = new File("io.txt");
		RandomAccessFile w = new RandomAccessFile(file, "rw");
		
		//设置指针的位置
		w.seek(file.length());
		
		//2.写入数据
		w.write("123abc木头人".getBytes());
		
		//3.关闭资源
		w.close();
	}
}

5.2 利用随机访问流 读取文件里的数据 RandomAccessFile

需求1:读取数据

public class Test03 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile r = new RandomAccessFile("io.txt", "r");

		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			System.out.println(new String(bs, 0, len));
		}
		
		//3.关闭资源
		r.close();
	}
}
5.2 利用随机访问流 读取文件里的数据 RandomAccessFile

需求2:从英文处开始读取数据

public class Test04 {
	public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile r = new RandomAccessFile("io.txt", "r");

		//设置指针的位置
		r.seek(3);
		
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			System.out.println(new String(bs, 0, len));
		}
		
		//3.关闭资源
		r.close();
	}
}
5.3 拷贝文件 – 断点续传
public class Copy {
	public static void main(String[] args) throws IOException {
		
		RandomAccessFile r = new RandomAccessFile("视频.mp4", "r");
		File targetFile = new File("copy.mp4");
		RandomAccessFile w = new RandomAccessFile(targetFile, "rw");
		
		//设置指针
		long fileLength = targetFile.length();
		r.seek(fileLength);
		w.seek(fileLength);
		
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			w.write(bs, 0, len);
		}
		
		r.close();
		w.close();
	}
}

简答题

什么是 java 序列化,如何实现 java 序列化?

序列化(钝化):将程序里的对象写入到文件

反序列化(活化):将文件里的对象读取到程序中

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题;

序列化的实现:将需要被序列化的类实现 Serializable 接口,该接口没有需实现的方法,implements Serializable 只是为了标注该对象是可被序列化的,然 后使用一个输出流(如 FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj) 方法就可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则用输入流。

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A 北枝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值