ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA 特殊操作流 对象序列化 Properties

2022-05-08 21:33:51  阅读:116  来源: 互联网

标签:java import public io new JAVA 序列化 Properties


 

标准输入输出流

 

System类中有两个静态的成员变量:

  • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
  • public static final PrintStream out:标准输出流。通常该流对应于显示输出或主机环境或用户指定的另一个输出目标

自己实现键盘录入数据:

  • BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

写起来太麻烦,Java就提供了一个类实现键盘录入

  • Scanner sc=new Scanner(System.in);

标准输入流的用法:

 1 import java.io.BufferedReader;
 2 import java.io.FileReader;
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.io.InputStreamReader;
 6 import java.util.Scanner;
 7 
 8 /*
 9 public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
10 */
11 public class SystemInDemo {
12     public static void main(String[] args) throws IOException {
13         //public static final InputStream in:标准输入流
14         //        InputStream is = System.in;
15 
16         //        int by;
17         //        while((by=is.read())!=-1) {
18         //            System.out.print((char)by);
19         //        }
20         /*
21         a
22         a
23         b
24         b
25         中
26         ??
27          */
28 
29         //如何把字节流转换为字符流?用转换流
30         //        InputStreamReader isr=;
31         //使用字符流能不能够实现一次读取一行数据呢?可以
32         //但是,一次读取一行数据的方法时字符缓冲输入流的特有方法
33         //        BufferedReader br=new BufferedReader(isr);
34 
35         //用一步来实现
36         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
37 
38         System.out.println("请输入一个字符串");
39         String line = br.readLine();
40         System.out.println("你输入的字符串是:" + line);
41 
42         System.out.println("请输入一个整数:");
43         int i = Integer.parseInt(br.readLine()); //要得到什么类型的字符串,就要用它对应的包装类的方法转换
44         System.out.println("你输入的整数是:" + i);
45 
46         //自己实现键盘录入数据太麻烦了,所以Java就提供了一个类供我们使用
47 //        Scanner sc = new Scanner(System.in);
48 
49     }
50 }

 

输出语句的本质:是一个标准的输出流

  • PrintStream ps = System.out;
  • PrintStream类有的方法,System.out都可以使用
 1 import java.io.PrintStream;
 2 
 3 /*
 4 public static final PrintStream out:标准输出流。通常该流对应于显示输出或主机环境或用户指定的另一个输出目标
 5 */
 6 public class SystemOutDemo {
 7     public static void main(String[] args) {
 8         // public static final PrintStream out:标准输出流
 9         PrintStream ps = System.out;
10 
11         // 能够方便地打印各种数据值
12 //        ps.print("hello");
13 //        ps.print(100);
14 
15 //        ps.println("hello");
16 //        ps.println(100);
17 
18         // System.out的本质是一个字节输出流
19         System.out.println("hello");
20         System.out.println(100);
21 
22         System.out.println();
23 //        System.out.print();//报错
24 
25     }
26 }

 

打印流

 

打印流分类:

  • 字节打印流:PrintStream
  • 字符打印流:PrintWriter

打印流特点:

  • 只负责输出数据,不负责读取数据
  • 有自己的特有方法

字节打印流

  • PrintStream(String fileName):使用指定的文件名创建新的打印流
  • 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出

字节打印流用法:

 1 import java.io.IOException;
 2 import java.io.PrintStream;
 3 
 4 /*
 5 打印流特点:
 6     只负责输出数据,不负责读取数据
 7     有自己的特有方法
 8 
 9 字节打印流
10     PrintStream(String fileName):使用指定的文件名创建新的打印流
11 */
12 
13 public class PrintStreamDemo {
14     public static void main(String[] args) throws IOException {
15         // PrintStream(String fileName):使用指定的文件名创建新的打印流
16         PrintStream ps = new PrintStream("..\\hello java\\ps.txt");
17 
18         // 写数据
19         // 字节输出流有的方法
20 //        ps.write(97);//a
21 
22         // 使用特有方法
23 //        ps.print(97);//97
24 //        ps.println();//换行
25 //        ps.print(98);//98
26 
27         ps.println(97);
28         ps.println(98);
29 
30         // 释放资源
31         ps.close();
32     }
33 }

 

字符打印流PrintWriter的构造方法:

 

 

 

 1 import java.io.FileWriter;
 2 import java.io.IOException;
 3 import java.io.PrintWriter;
 4 
 5 /*
 6 字符打印流PrintWriter的构造方法:
 7 
 8 PrintWriter (String fileName)使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
 9 
10 PrintWriter(Writer out,boolean autoFlush)创建一个新的PrintWriter 
11         1.out:字符输出流 
12         2.antoFlush:一个布尔值,如果为真,则println,printf,或format方法将刷新输出缓冲区
13 */
14 public class PrintWriterDemo {
15     public static void main(String[] args) throws IOException {
16         // PrintWriter (String fileName)使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
17 //        PrintWriter pw=new PrintWriter("..\\hello java\\pw.txt");
18 
19 //        pw.write("hello");
20 //        pw.write("\r\n");//加换行符
21 //        pw.flush();//字符流,需要刷新,否则不出来
22 //        
23 //        pw.write("world");
24 //        pw.write("\r\n");
25 //        pw.flush();
26 
27 //        pw.println("hello");
28         /*相当于:
29             pw.write("hello");
30             pw.write("\r\n");
31         */
32 //        pw.flush();//还是需要刷新,比较麻烦
33 //        pw.println("world");
34 //        pw.flush();
35 
36         // PrintWriter(Writer out,boolean autoFlush)创建一个新的PrintWriter
37         PrintWriter pw = new PrintWriter(new FileWriter("..\\hello java\\pw.txt"), true);// 实现自动刷新
38 //        PrintWriter pw=new PrintWriter(new FileWriter("..\\hello java\\pw.txt"),false);
39 
40         pw.println("hello");
41         /*相当于:
42             pw.write("hello");
43             pw.write("\r\n");
44             pw.flush();
45          */
46         pw.println("world");
47 
48         pw.close();
49 
50     }
51 }

 

案例:复制Java文件(打印流改进版)

需求:把模块目录下的PrintStreamDemo.java复制到模块目录下的Copy.java

思路:

  1. 根据数据源创建字符输入流对象
  2. 根据目的地创建字符输出流对象
  3. 读写数据,复值文件
  4. 释放资源
 1 import java.io.BufferedReader;
 2 import java.io.BufferedWriter;
 3 import java.io.FileReader;
 4 import java.io.FileWriter;
 5 import java.io.IOException;
 6 import java.io.PrintWriter;
 7 
 8 /*
 9 案例:复制Java文件(打印流改进版)
10 
11 需求:把模块目录下的PrintStreamDemo.java复制到模块目录下的Copy.java
12 
13 思路:
14      1. 根据数据源创建字符输入流对象
15      2. 根据目的地创建字符输出流对象
16      3. 读写数据,复值文件
17      4. 释放资源
18 */
19 public class CopyJavaDemo {
20     public static void main(String[] args) throws IOException {
21         /*//1. 根据数据源创建字符输入流对象
22         BufferedReader br=new BufferedReader(new FileReader("..\\hello java\\PrintStreamDemo.java"));
23         //2. 根据目的地创建字符输出流对象
24         BufferedWriter bw=new BufferedWriter(new FileWriter("..\\hello java\\Copy.java"));
25         //3. 读写数据,复值文件
26         String line;
27         while((line=br.readLine())!=null) {
28             bw.write(line);
29             bw.newLine();
30             bw.flush();
31         }
32         //4. 释放资源
33         br.close();
34         bw.close();*/
35 
36         // 1. 根据数据源创建字符输入流对象
37         BufferedReader br = new BufferedReader(new FileReader("..\\hello java\\PrintStreamDemo.java"));
38         // 2. 根据目的地创建字符输出流对象
39         PrintWriter pw = new PrintWriter(new FileWriter("..\\hello java\\Copy.java"), true);
40 
41         String line;
42         while ((line = br.readLine()) != null) {
43             pw.println(line);
44         }
45         // 4. 释放资源
46         br.close();
47         pw.close();
48 
49     }
50 }

 

对象序列化流

 

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

要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:

  • 对象序列化流:ObjectOutputStream
  • 对象反序列化流:ObjectInputStream

 

对象序列化流

对象序列化流:ObjectOutputStream

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

构造方法:

  • ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法:

  • void writeObject(Object obj):将指定的对象写入ObjectOutputStream

注意:

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

对象序列化的用法:

 1 import java.io.Serializable;
 2 
 3 public class Student implements Serializable {
 4     private String name;
 5     private int age;
 6 
 7     public String getName() {
 8         return name;
 9     }
10 
11     public void setName(String name) {
12         this.name = name;
13     }
14 
15     public int getAge() {
16         return age;
17     }
18 
19     public void setAge(int age) {
20         this.age = age;
21     }
22 
23     public Student(String name, int age) {
24         super();
25         this.name = name;
26         this.age = age;
27     }
28 
29     public Student() {
30         super();
31     }
32 
33 }
 1 import java.io.FileOutputStream;
 2 import java.io.IOException;
 3 import java.io.ObjectOutputStream;
 4 
 5 /*
 6 对象序列化流
 7 构造方法:
 8 
 9 - ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
10 
11 序列化对象的方法:
12 
13  - void writeObject(Object obj):将指定的对象写入ObjectOutputStream
14 
15     NotSerializableException:抛出一个实例需要一个Serializable接口。序列化运行时或实例的类可能会抛出此异常
16     类的序列化由实现java.io.Serializable接口的类启用。不实现此接口的类将不会使用任何状态序列化或反序列化
17     
18 */
19 public class ObjectOutputStreamDemo {
20     public static void main(String[] args) throws IOException {
21         // ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
22         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("..\\hello java\\oos.txt"));
23 
24         // 创建对象
25         Student s = new Student("小白", 12);
26 
27         // void writeObject(Object obj):将指定的对象写入ObjectOutputStream
28         oos.writeObject(s);
29 
30         oos.close();
31     }
32 }

 

对象反序列化流:ObjectInputStream

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

构造方法:

  • ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法:

  • Object readObject():从ObjectInputStream读取一个对象

对象反序列化的用法:

 1 import java.io.FileInputStream;
 2 import java.io.IOException;
 3 import java.io.ObjectInputStream;
 4 
 5 /*
 6 对象反序列化流:ObjectInputStream
 7 
 8 - ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
 9 
10 构造方法:
11 
12 - ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
13 
14 反序列化对象的方法:
15 
16 - Object readObject():从ObjectInputStream读取一个对象
17 */
18 public class ObjectInputStreamDemo {
19     public static void main(String[] args) throws IOException, ClassNotFoundException {
20         // ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
21         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("..\\hello java\\oos.txt"));
22 
23         // Object readObject():从ObjectInputStream读取一个对象
24         Object obj = ois.readObject();// 抛出异常
25 
26         Student s = (Student) obj;// 向下转型
27         System.out.println(s.getName() + "," + s.getAge());// 小白,12
28 
29         ois.close();
30     }
31 }

 

对象系列化流中的三个问题

 

用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

  • 会出问题,抛出InvalidClassException异常

 

如果出问题了,如何解决呢?

  • 给对象所属的类加一个seriaLVersionUID

private static final long seriaLVersionUID=42L;

 

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

  • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程

 

 1 import java.io.Serializable;
 2 
 3 public class Student implements Serializable {
 4     private static final long serialVersionUID = 42L;
 5     private String name;
 6 //    private int age;
 7     private transient int age;// 被transient关键字修饰的成员变量,不参与序列化过程
 8 
 9     public String getName() {
10         return name;
11     }
12 
13     public void setName(String name) {
14         this.name = name;
15     }
16 
17     public int getAge() {
18         return age;
19     }
20 
21     public void setAge(int age) {
22         this.age = age;
23     }
24 
25     public Student(String name, int age) {
26         super();
27         this.name = name;
28         this.age = age;
29     }
30 
31     public Student() {
32         super();
33     }
34 
35     // 修改了类文件
36     @Override
37     public String toString() {
38         return "Student [name=" + name + ", age=" + age + "]";
39     }
40 
41 }
 1 import java.io.FileInputStream;
 2 import java.io.FileOutputStream;
 3 import java.io.IOException;
 4 import java.io.ObjectInputStream;
 5 import java.io.ObjectOutputStream;
 6 
 7 /*
 8 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
 9     java.io.InvalidClassException: 
10         当序列化运行时检测到类中的以下问题之一时抛出。
11             类的串行版本与从流中读取的类描述符的类型不匹配
12             该类包含未知的数据类型
13             该类没有课访问的无参数构造函数
14             
15     Contents2.Student; local class incompatible: 
16     stream classdesc serialVersionUID = -7792934128464322290,
17     local class serialVersionUID = -394614500484104815
18     序列化版本号不同
19     
20 如果出问题了,如何解决呢?
21     给对象所属的类加一个值:private static final long seriaLVersionUID=42L;
22 
23 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
24     private transient int age;
25 
26 */
27 
28 public class ObjectStreamDemo {
29     public static void main(String[] args) throws IOException, ClassNotFoundException {
30 //        write();
31         read();
32 
33     }
34 
35     // 反序列化
36     private static void read() throws IOException, ClassNotFoundException {
37         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("..\\hello java\\oos.txt"));
38         Object obj = ois.readObject();
39         Student s = (Student) obj;
40         System.out.println(s.getName() + "," + s.getAge());
41         ois.close();
42 
43     }
44 
45     // 序列化
46     private static void write() throws IOException {
47         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("..\\hello java\\oos.txt"));
48         Student s = new Student("小白", 12);
49         oos.writeObject(s);
50         oos.close();
51 
52     }
53 
54 }

 

标签:java,import,public,io,new,JAVA,序列化,Properties
来源: https://www.cnblogs.com/cuipengchong/p/16246971.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有