1.1标准输入流
1. System类中有两个静态的成员变量
2. 示例代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) throws IOException {
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);
Scanner sc = new Scanner(System.in);
}
}
1.2 标准输出流
1. System类中有两个静态的成员变量
public static final InputStream in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源public static final PrintStream out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
2. 输出语句的本质
3. 示例代码
import java.io.PrintStream;
public class Demo {
public static void main(String[] args) {
PrintStream ps = System.out;
System.out.print("java");
System.out.print(100);
System.out.println("java");
System.out.println(100);
}
}
1.3 字节打印流
1. 打印流分类
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
2. 打印流的特点
- 只负责输出数据,不负责读取数据
- 永远不会抛出IOException
- 有自己的特有方法
3. 字节打印流
PrintStream(String fileName)
:使用指定的文件名创建新的打印流- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
- 可以改变输出语句的目的地
public static void setOut(PrintStream out)
:重新分配“标准”输出流
4. 示例代码
import java.io.IOException;
import java.io.PrintStream;
public class Demo {
public static void main(String[] args) throws IOException {
PrintStream ps = new PrintStream("myOtherStream\\ps.txt");
ps.println(97);
ps.println(98);
ps.close();
}
}
1.4 字符打印流
1. 字符打印流构造房方法
方法名 | 说明 |
---|
PrintWriter(String fileName) | 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新 |
PrintWriter(Writerout, boolean autoFlush) | 创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区 |
2. 示例代码
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Demo {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),true);
pw.println("hello");
pw.println("world");
pw.close();
}
}
1.5 对象序列化流
1. 对象序列化介绍
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
2. 对象序列化流: ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
- 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
3. 构造方法
方法名 | 说明 |
---|
ObjectOutputStream(OutputStream out) | 创建一个写入指定的OutputStream的ObjectOutputStream |
4. 序列化对象的方法
方法名 | 说明 |
---|
void writeObject(Object obj) | 将指定的对象写入ObjectOutputStream |
5. 注意事项
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
6. 示例代码
import java.io.*;
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 +
'}';
}
}
public class Demo {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
Student s = new Student("小明",18);
oos.writeObject(s);
oos.close();
}
}
1.6 对象反序列化流
1. 对象反序列化流: ObjectInputStream
ObjectInputStream
反序列化先前使用ObjectOutputStream
编写的原始数据和对象
2. 构造方法
方法名 | 说明 |
---|
ObjectInputStream(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
3. 反序列化对象的方法
方法名 | 说明 |
---|
Object readObject() | 从ObjectInputStream读取一个对象 |
4. 示例代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
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 Demo {
public static void main(String[] args) 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();
}
}
1.7 serialVersionUID 和 transient
1. serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会抛出
InvalidClassException
异常 - 如何解决?
- 重新序列化
- 给对象所属的类加一个
serialVersionUID
private static final long serialVersionUID = 42L;
2. transient
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加
transient
关键字修饰,该关键字标记的成员变量不参与序列化过程
3. 示例代码
import java.io.*;
class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
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 Demo {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
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();
}
}