• 19 Java 转换流&& 对象操作流 && Properties集合


    2.转换流

    2.1字符流中和编码解码问题相关的两个类【理解】

    • InputStreamReader:是从字节流到字符流的桥梁,父类是Reader

      ​ 它读取字节,并使用指定的编码将其解码为字符

      ​ 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

    • OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer

      ​ 是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节

      ​ 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

    2.2转换流读写数据【应用】

    • 构造方法

      方法名说明
      InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
      InputStreamReader(InputStream in,String chatset)使用指定的字符编码创建InputStreamReader对象
      OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
      OutputStreamWriter(OutputStream out,String charset)使用指定的字符编码创建OutputStreamWriter对象
    • 代码演示

      public class ConversionStreamDemo {
          public static void main(String[] args) throws IOException {
              //OutputStreamWriter osw = new OutputStreamWriter(new                                             FileOutputStream("myCharStream\\osw.txt"));
              OutputStreamWriter osw = new OutputStreamWriter(new                                              FileOutputStream("myCharStream\\osw.txt"),"GBK");
              osw.write("中国");
              osw.close();
      
              //InputStreamReader isr = new InputStreamReader(new 	                                         FileInputStream("myCharStream\\osw.txt"));
              InputStreamReader isr = new InputStreamReader(new                                                 FileInputStream("myCharStream\\osw.txt"),"GBK");
              //一次读取一个字符数据
              int ch;
              while ((ch=isr.read())!=-1) {
                  System.out.print((char)ch);
              }
              isr.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    3.对象操作流

    3.1对象序列化流【应用】

    • 对象序列化介绍

      • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
      • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
      • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
      • 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
    • 对象序列化流: ObjectOutputStream

      • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
    • 构造方法

      方法名说明
      ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream
    • 序列化对象的方法

      方法名说明
      void writeObject(Object obj)将指定的对象写入ObjectOutputStream
    • 示例代码

      学生类

      public class Student implements Serializable {
          private String name;
          private int age;
      
          public Student() {
          }
      
          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;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36

      测试类

      public class ObjectOutputStreamDemo {
          public static void main(String[] args) throws IOException {
              //ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
      
              //创建对象
              Student s = new Student("佟丽娅",30);
      
              //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
              oos.writeObject(s);
      
              //释放资源
              oos.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 注意事项

      • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
      • Serializable是一个标记接口,实现该接口,不需要重写任何方法

    3.2对象反序列化流【应用】

    • 对象反序列化流: ObjectInputStream

      • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
    • 构造方法

      方法名说明
      ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream
    • 反序列化对象的方法

      方法名说明
      Object readObject()从ObjectInputStream读取一个对象
    • 示例代码

      public class ObjectInputStreamDemo {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
              //ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
              ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
      
              //Object readObject():从ObjectInputStream读取一个对象
              Object obj = ois.readObject();
      
              Student s = (Student) obj;
              System.out.println(s.getName() + "," + s.getAge());
      
              ois.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    3.3 serialVersionUID&transient【应用】

    • serialVersionUID

      • 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
        • 会出问题,会抛出InvalidClassException异常
      • 如果出问题了,如何解决呢?
        • 重新序列化
        • 给对象所属的类加一个serialVersionUID
          • private static final long serialVersionUID = 42L;
    • transient

      • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
        • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
    • 示例代码

      学生类

      public class Student implements Serializable {
          private static final long serialVersionUID = 42L;
          private String name;
      //    private int age;
          private transient int age;
      
          public Student() {
          }
      
          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;
          }
      
      //    @Override
      //    public String toString() {
      //        return "Student{" +
      //                "name='" + name + '\'' +
      //                ", age=" + age +
      //                '}';
      //    }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38

      测试类

      public class ObjectStreamDemo {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
      //        write();
              read();
          }
      
          //反序列化
          private static void read() throws IOException, ClassNotFoundException {
              ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
              Object obj = ois.readObject();
              Student s = (Student) obj;
              System.out.println(s.getName() + "," + s.getAge());
              ois.close();
          }
      
          //序列化
          private static void write() throws IOException {
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
              Student s = new Student("佟丽娅", 30);
              oos.writeObject(s);
              oos.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

    3.4对象操作流练习【应用】

    • 案例需求

      创建多个学生类对象写到文件中,再次读取到内存中

    • 实现步骤

      • 创建序列化流对象
      • 创建多个学生对象
      • 将学生对象添加到集合中
      • 将集合对象序列化到文件中
      • 创建反序列化流对象
      • 将文件中的对象数据,读取到内存中
    • 代码实现

      学生类

      public class Student implements Serializable{
          
          private static final long serialVersionUID = 2L;
      
          private String name;
          private int age;
      
          public Student() {
          }
      
          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;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31

      测试类

      public class Demo03 {
          /**
           *  read():
           *      读取到文件末尾返回值是 -1
           *  readLine():
           *      读取到文件的末尾返回值 null
           *  readObject():
           *      读取到文件的末尾 直接抛出异常
           *  如果要序列化的对象有多个,不建议直接将多个对象序列化到文件中,因为反序列化时容易出异常
           *      建议: 将要序列化的多个对象存储到集合中,然后将集合序列化到文件中
           */
          public static void main(String[] args) throws Exception {
              /*// 序列化
              //1.创建序列化流对象
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myCode\\oos.txt"));
              ArrayList arrayList = new ArrayList<>();
              //2.创建多个学生对象
              Student s = new Student("佟丽娅",30);
              Student s01 = new Student("佟丽娅",30);
              //3.将学生对象添加到集合中
              arrayList.add(s);
              arrayList.add(s01);
              //4.将集合对象序列化到文件中
              oos.writeObject(arrayList);
              oos.close();*/
      
              // 反序列化
            	//5.创建反序列化流对象
              ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myCode\\oos.txt"));
            	//6.将文件中的对象数据,读取到内存中
              Object obj = ois.readObject();
              ArrayList<Student> arrayList = (ArrayList<Student>)obj;
              ois.close();
              for (Student s : arrayList) {
                  System.out.println(s.getName() + "," + s.getAge());
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38

    4.Properties集合

    4.1Properties作为Map集合的使用【应用】

    • Properties介绍

      • 是一个Map体系的集合类
      • Properties可以保存到流中或从流中加载
      • 属性列表中的每个键及其对应的值都是一个字符串
    • Properties基本使用

      public class PropertiesDemo01 {
          public static void main(String[] args) {
              //创建集合对象
      //        Properties prop = new Properties(); //错误
              Properties prop = new Properties();
      
              //存储元素
              prop.put("itheima001", "佟丽娅");
              prop.put("itheima002", "赵丽颖");
              prop.put("itheima003", "刘诗诗");
      
              //遍历集合
              Set<Object> keySet = prop.keySet();
              for (Object key : keySet) {
                  Object value = prop.get(key);
                  System.out.println(key + "," + value);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

    4.2Properties作为Map集合的特有方法【应用】

    • 特有方法

      方法名说明
      Object setProperty(String key, String value)设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
      String getProperty(String key)使用此属性列表中指定的键搜索属性
      Set stringPropertyNames()从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
    • 示例代码

      public class PropertiesDemo02 {
          public static void main(String[] args) {
              //创建集合对象
              Properties prop = new Properties();
      
              //Object setProperty(String key, String value):设置集合的键和值,都是String类型
              prop.setProperty("itheima001", "佟丽娅");
              prop.setProperty("itheima002", "赵丽颖");
              prop.setProperty("itheima003", "刘诗诗");
      
              //String getProperty(String key):使用此属性列表中指定的键搜索属性
      //        System.out.println(prop.getProperty("itheima001"));
      //        System.out.println(prop.getProperty("itheima0011"));
      
      //        System.out.println(prop);
      
              //Set stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
              Set<String> names = prop.stringPropertyNames();
              for (String key : names) {
      //            System.out.println(key);
                  String value = prop.getProperty(key);
                  System.out.println(key + "," + value);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

    4.3Properties和IO流相结合的方法【应用】

    • 和IO流结合的方法

      方法名说明
      void load(Reader reader)从输入字符流读取属性列表(键和元素对)
      void store(Writer writer, String comments)将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流
    • 示例代码

      public class PropertiesDemo03 {
          public static void main(String[] args) throws IOException {
              //把集合中的数据保存到文件
      //        myStore();
      
              //把文件中的数据加载到集合
              myLoad();
      
          }
      
          private static void myLoad() throws IOException {
              Properties prop = new Properties();
      
              //void load(Reader reader):
              FileReader fr = new FileReader("myOtherStream\\fw.txt");
              prop.load(fr);
              fr.close();
      
              System.out.println(prop);
          }
      
          private static void myStore() throws IOException {
              Properties prop = new Properties();
      
              prop.setProperty("itheima001","佟丽娅");
              prop.setProperty("itheima002","赵丽颖");
              prop.setProperty("itheima003","刘诗诗");
      
              //void store(Writer writer, String comments):
              FileWriter fw = new FileWriter("myOtherStream\\fw.txt");
              prop.store(fw,null);
              fw.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34

    4.4Properties集合练习【应用】

    • 案例需求

      在Properties文件中手动写上姓名和年龄,读取到集合中,将该数据封装成学生对象,写到本地文件

    • 实现步骤

      • 创建Properties集合,将本地文件中的数据加载到集合中
      • 获取集合中的键值对数据,封装到学生对象中
      • 创建序列化流对象,将学生对象序列化到本地文件中
    • 代码实现

      学生类

      public class Student implements Serializable {
          private static final long serialVersionUID = 1L;
      
          private String name;
          private int age;
      
          public Student() {
          }
      
          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;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38

      测试类

      public class Test {
      
          public static void main(String[] args) throws IOException {
            	//1.创建Properties集合,将本地文件中的数据加载到集合中
              Properties prop = new Properties();
              FileReader fr = new FileReader("prop.properties");
              prop.load(fr);
              fr.close();
      		//2.获取集合中的键值对数据,封装到学生对象中
              String name = prop.getProperty("name");
              int age = Integer.parseInt(prop.getProperty("age"));
              Student s = new Student(name,age);
      		//3.创建序列化流对象,将学生对象序列化到本地文件中
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
              oos.writeObject(s);
              oos.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
  • 相关阅读:
    极端气候?自然灾害?【实战】机器学习预测森林火灾
    STM32低功耗分析
    责任链模式
    NAT-DDNS内网穿透技术,快解析DDNS的优势
    【一刷《剑指Offer》】面试题 9:斐波那契数列(扩展:青蛙跳台阶、矩阵覆盖)
    【毕业设计】基于Android的餐饮管理系统APP毕业设计源码
    数据分析大作战,SQL V.S. Python,来看看这些考题你都会吗 ⛵
    108. 将有序数组转换为二叉搜索树
    LDO(线性稳压器)设计检查
    线性与树型数据结构可视化模拟器
  • 原文地址:https://blog.csdn.net/qq_52330730/article/details/126015862