java-字符流和字节流(三)
一、IO特殊操作流
1.1 标准流
1.1.1 标准输入流
-
System
类中有两个静态的成员变量- public static final InputStream
in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源 - public static final PrintStream
out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
- public static final InputStream
-
实现键盘录入数据
public class SystemInDemo { public static void main(String[] args) throws IOException { //public static final InputStream in:标准输入流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入一个字符串:"); String line = br.readLine(); System.out.println("你输入的字符串是:" + line); System.out.println("请输入一个整数:"); int i = Integer.parseInt(br.readLine()); System.out.println("你输入的整数是:" + i); //自己实现键盘录入数据太麻烦了,所以Java就提供了一个类供我们使用 Scanner sc = new Scanner(System.in); } }
1.1.2标准输出流
-
System
类中有两个静态的成员变量- public static final InputStream
in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源 - public static final PrintStream
out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
- public static final InputStream
-
输出语句的本质:是一个标准的输出流
- PrintStream ps = System.out;
- PrintStream类有的方法,System.out都可以使用
-
示例代码
public class SystemOutDemo { public static void main(String[] args) { //public static final PrintStream out:标准输出流 PrintStream ps = System.out; //能够方便地打印各种数据值 ps.println("hello"); ps.println(100); //System.out的本质是一个字节输出流 System.out.println("hello"); System.out.println(100); } }
1.2 打印流
-
打印流分类
- 字节打印流:
PrintStream
- 字符打印流:
PrintWriter
- 字节打印流:
-
打印流的特点
- 只负责输出数据,不负责读取数据
- 永远不会抛出IOException
- 有自己的特有方法
1.2.1 字节打印流
- PrintStream(String fileName):使用指定的文件名创建新的打印流
- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
- 可以改变输出语句的目的地
public static void setOut(PrintStream out):重新分配“标准”输出流
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
//PrintStream(String fileName):使用指定的文件名创建新的打印流
PrintStream ps = new PrintStream("myOtherStream\\ps.txt");
//写数据
//字节输出流有的方法
ps.write(97);
//使用特有方法写数据
ps.println(97);
ps.println(98);
//释放资源
ps.close();
}
}
1.2.2 字符打印流
-
字符打印流构造方法
方法名 说明 PrintWriter(String fileName) 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新 PrintWriter(Writer out, boolean autoFlush) 创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区 -
示例代码
public class PrintWriterDemo { public static void main(String[] args) throws IOException { //PrintWriter(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新 PrintWriter pw = new PrintWriter("myOtherStream\\pw.txt"); pw.write("hello"); pw.write("\r\n"); pw.flush(); pw.write("world"); pw.write("\r\n"); pw.flush(); //PrintWriter(Writer out, boolean autoFlush):创建一个新的PrintWriter PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),true); pw.println("hello"); pw.println("world"); pw.close(); } }
1.3 对象序列化
对象序列化介绍
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
1.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; } }
-
测试类
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(); } }
-
-
注意事项
- 一个对象要想被序列化,该对象所属的类
必须必须实现Serializable
接口 Serializable
是一个标记接口
,实现该接口,不需要重写任何方法
- 一个对象要想被序列化,该对象所属的类
1.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.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; }
-
测试类
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(); } }
-
Ending…