Java基础关键_025_IO流(三)

news/2025/3/28 10:54:52/

目  录

一、数据输入输出流

1.DataOutputStream

2.DataInputStream

二、序列化和反序列化

1.ObjectOutputStream

2.ObjectInputStream 

3.Serializable 接口

(1)说明

(2)实例

4.序列化版本号

(1)说明

(2)实例 

5.transient 关键字

三、打印流

 1.PrintStream

 2.PrintWriter


一、数据输入输出流

1.DataOutputStream

  1. 数据字节数输出流;
  2. 将 Java 程序中的数据直接写入文件,直接是二进制;
  3. 效率较高,因为不需要转码;
  4. 只能由 DataInputStream 读取。
java">public class DataOutputStreamTest {public static void main(String[] args) {try (DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("D:\\Test.txt"))) {byte b = 127;short s = 100;int i = 999;long l = 666666;float f = 2.1F;double d = 520.1314;char c = 'a';String str1 = "女也不爽,士贰其行。";String str2 = "士也罔极,二三其德。";boolean boo = true;dataOutputStream.writeByte(b);dataOutputStream.writeShort(s);dataOutputStream.writeInt(i);dataOutputStream.writeLong(l);dataOutputStream.writeFloat(f);dataOutputStream.writeDouble(d);dataOutputStream.writeChar(c);dataOutputStream.write("\n".getBytes());dataOutputStream.writeChars(str1);dataOutputStream.writeUTF(str2);dataOutputStream.writeUTF("\n");dataOutputStream.writeBoolean(boo);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}


2.DataInputStream

  1. 数据字节输入流;
  2. 特用来读取 DataOutputStream 流写入的文件;
  3. 读取的顺序要与写入的顺序一致。
java">public class DataInputStreamTest {public static void main(String[] args) {try (DataInputStream dataInputStream = new DataInputStream(new FileInputStream("D:\\Test.txt"))) {System.out.println(dataInputStream.readByte()); // 127System.out.println(dataInputStream.readShort());    // 100System.out.println(dataInputStream.readInt());  // 999System.out.println(dataInputStream.readLong()); // 666666System.out.println(dataInputStream.readFloat());    // 2.1System.out.println(dataInputStream.readDouble());   // 520.1314System.out.println(dataInputStream.readChar()); // aSystem.out.println(dataInputStream.readUTF());  // 女也不爽,士贰其行。System.out.println(dataInputStream.readUTF());  //   士也罔极,二三其德。System.out.println(dataInputStream.readBoolean());  // true} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}
}

二、序列化和反序列化

1.ObjectOutputStream

  1. 对象字节输出流;
  2. 完成对象序列化,可以将 JVM 中的 Java 对象序列化到文件或者网络中;
  3. 序列化是将 Java 对象转换为字节序列的过程。
java">public class ObjectOutputStreamTest {public static void main(String[] args) {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Test.txt"))) {String str = "落霞与孤鹜齐飞,秋水共长天一色。";objectOutputStream.writeObject(str);} catch (IOException e) {throw new RuntimeException(e);}}
}


2.ObjectInputStream 

  1. 对象字节输入流;
  2. 完成反序列化,可以将字节序列转换为 JVM 中的 Java 对象。
java">public class ObjectInputStreamTest {public static void main(String[] args) {try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\Test.txt"))) {Object o = objectInputStream.readObject();System.out.println(o);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}
}


3.Serializable 接口

(1)说明

  1. 参与序列化和反序列化的对象必须实现 java.io.Serializable 接口;
  2. 该接口是一个标志接口,其内部没有任何方法。

(2)实例

java">public class ObjectOutputStreamTest {public static void main(String[] args) {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Test.txt"))) {Student s1 = new Student("王勃", 29);Student s2 = new Student("李白", 32);Student s3 = new Student("杜甫", 33);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);objectOutputStream.writeObject(arrayList);} catch (IOException e) {e.printStackTrace();}}
}
java">public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

 

        若没有实现 Serializable 接口,则会报不可序列化异常,因此需要实现这个标志接口。

        public class Student implements Serializable {

                ……

        }

java">public class ObjectInputStreamTest {public static void main(String[] args) {try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\Test.txt"))) {Object o = objectInputStream.readObject();System.out.println(o);// [Student{name='王勃', age=29}, Student{name='李白', age=32}, Student{name='杜甫', age=33}]} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}
}

4.序列化版本号

(1)说明

  1. 当 Java 程序实现了 Serializable 接口,编译器会自动给该类添加一个【序列化版本号】;
  2. Java 首先通过类名,其次通过序列化版本号区分 Class 版本;
  3. 每次改动程序代码,会生成一个新的序列化版本号;
  4. 如果确定类还是原来的类,本身合法,而想要保证序列化、反序列化成功,则需要定义序列化版本号并赋值。   

(2)实例 

java">public class Student implements Serializable {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
java">public class ObjectOutputStreamTest {public static void main(String[] args) {try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Test.txt"))) {Student s1 = new Student("王勃", 29);Student s2 = new Student("李白", 32);Student s3 = new Student("杜甫", 33);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);objectOutputStream.writeObject(arrayList);} catch (IOException e) {e.printStackTrace();}}
}
java">public class ObjectInputStreamTest {public static void main(String[] args) {try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\Test.txt"))) {Object o = objectInputStream.readObject();System.out.println(o);// [Student{name='王勃', age=29}, Student{name='李白', age=32}, Student{name='杜甫', age=33}]} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}
}

        对此序列化和反序列化都正常,但是之后若是对 Student 类进行修改(例如:新增属性及相关方法)后再进行反序列化操作,会出现 java.io.InvalidClassException 异常。

        所以需要指定序列化版本号,就保证了反序列化的正常进行。


        public class Student implements Serializable {

                @Serial

                private static final long serialVersionUID = 1L;

                ……

        }                     


5.transient 关键字

        其修饰的属性不会参与序列化。

java">public class Student implements Serializable {@Serialprivate static final long serialVersionUID = 1L;private String name;private transient int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}

        用 transient 修饰 age 属性,序列化和反序列化后,可以看到所有 Student 对象的年龄都是 0 。 


三、打印流

 1.PrintStream

  1. 字节打印流;
  2. 提供便捷的打印方法和格式化输出,主要打印内容到文件或控制台;
  3. 可以直接输出各种数据类型;
  4. 可以自动刷新和自动换行;
  5. 支持字符串转义;
  6. 自动根据环境选择合适的编码方式;
  7. 不需要手动刷新,自动刷新;
  8. 常用方法有:print()、println()、printf();
  9. 调用 printf 方法可以格式化输出:
    1. 【%s】表示字符串;
    2. 【%d】表示整数;
    3. 【%f】表示小数(【%.2f】表示保留两位小数 );
    4. 【%c】表示字符。

 2.PrintWriter

  1. 字符打印流;
  2. 需要手动刷新;
  3. 常用方法有:print()、println()、printf()。

http://www.ppmy.cn/news/1580709.html

相关文章

蓝桥杯练习day1:拆分数位-四位数字的最小和

前言 给你一个四位 正 整数 num 。请你使用 num 中的 数位 &#xff0c;将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 &#xff0c;且 num 中 所有 数位都必须使用。 比方说&#xff0c;给你 num 2932 &#xff0c;你拥有的数位包括&#xff1a;两…

Matlab 液位系统根据输入和输出信号拟合一阶传递函数

1、内容简介 略 Matlab165-液位系统根据输入和输出信号拟合一阶传递函数 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略

【C++】二叉树和堆的链式结构(上)

本篇博客给大家带来的是用C语言来实现堆链式结构和二叉树的实现&#xff01; &#x1f41f;&#x1f41f;文章专栏&#xff1a;数据结构 &#x1f680;&#x1f680;若有问题评论区下讨论&#xff0c;我会及时回答 ❤❤欢迎大家点赞、收藏、分享&#xff01; 今日思想&#xff…

golang快速上手基础语法

变量 第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0 package mainimport "fmt"func main() {var a int //第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0。fmt.Printf(" a %d\n"…

RHCE(RHCSA复习:npm、dnf、源码安装实验)

七、软件管理 7.1 rpm 安装 7.1.1 挂载 [rootlocalhost ~]# ll /mnt total 0 drwxr-xr-x. 2 root root 6 Oct 27 21:32 hgfs[rootlocalhost ~]# mount /dev/sr0 /mnt #挂载 mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# [rootlo…

Pytest项目_day01(HTTP接口)

HTTP HTTP是一个协议&#xff08;服务器传输超文本到浏览器的传送协议&#xff09;&#xff0c;是基于TCP/IP通信协议来传输数据&#xff08;HTML文件&#xff0c;图片文件&#xff0c;查询结果等&#xff09;。 访问域名 例如www.baidu.com就是百度的域名&#xff0c;我们想…

在 Visual Studio Code 中高效使用 Pylance:配置、技巧与插件对比

在 Visual Studio Code 中高效使用 Pylance&#xff1a;配置、技巧与插件对比 目录 什么是 Pylance&#xff1f;安装与启用核心配置详解高效使用技巧Pylance vs Jedi&#xff1a;深度对比常见问题与优化总结 1. 什么是 Pylance&#xff1f; ‌Pylance‌ 是微软为 VSCode Pyth…

Github 2025-03-19 C开源项目日报 Top4

根据Github Trendings的统计,今日(2025-03-19统计)共有4个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目4Valkey: 一个高性能数据结构服务器 创建周期:8 天开发语言:C协议类型:BSD 3-Clause “New” or “Revised” LicenseStar数量:2775 个…