1.IO特殊操作流
1.1 标准输入流
System类中有两个静态的成员变量
public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源。
public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的 另一个输出目标。
1.2 标准输出流
System类中有两个静态的成员变量
public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源。
public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标。
1.3 字节打印流
打印流分类
字节打印流:PrintStream
字符打印流:PrintWriter
打印流的特点
只负责输出数据,不负责读取数据
永远不会抛出IOException
有自己的特有方法
字节打印流
PrintStream(String fileName):使用指定的文件名创建新的打印流
使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
可以改变输出语句的目的地
public static void setOut(PrintStream out):重新分配“标准”输出流
1.4 字符打印流
方法名 | 说明 |
PrintWriter(String fileName) | 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新 |
PrintWriter(Writer out, boolean autoFlush) | 创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果 为真,则println , printf或format方法将刷新输出缓冲区 |
1.5 对象序列化流
对象序列化介绍
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
对象序列化流: ObjectOutputStream
将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
构造方法
方法名 | 说明 |
ObjectOutputStream(OutputStream out) | 创建一个写入指定的OutputStream的 ObjectOutputStream |
序列化对象的方法
方法名 | 说明 |
void writeObject(Object obj) | 将指定的对象写入ObjectOutputStream |
学生类
1 import java.io.Serializable;
2
3 public class Student implements Serializable {
4 private String name;
5 private int age;
6
7 public Student() {
8 }
9
10 public Student(String name, int age) {
11 this.name = name;
12 this.age = age;
13 }
14
15 public String getName() {
16 return name;
17 }
18
19 public void setName(String name) {
20 this.name = name;
21 }
22
23 public int getAge() {
24 return age;
25 }
26
27 public void setAge(int age) {
28 this.age = age;
29 }
30
31 @Override
32 public boolean equals(Object o) {
33 if (this == o) return true;
34 if (o == null || getClass() != o.getClass()) return false;
35
36 Student student = (Student) o;
37
38 if (age != student.age) return false;
39 return name != null ? name.equals(student.name) : student.name == null;
40 }
41
42 @Override
43 public int hashCode() {
44 int result = name != null ? name.hashCode() : 0;
45 result = 31 * result + age;
46 return result;
47 }
48
49 @Override
50 public String toString() {
51 return "Student{" +
52 "name='" + name + '\'' +
53 ", age=" + age +
54 '}';
55 }
56 }
测试类
1 import java.io.*;
2
3 public class OOP {
4 public static void main(String[] args) throws IOException {
5 File file = new File("F:\\oos.yz");
6 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
7
8 Student s = new Student("yz", 22);
9
10 oos.writeObject(s);
11
12 oos.close();
13 }
14 }
注意事项
一个对象要想被序列化,该对象所属的类必须必须实现Serializable接口
Serializable是一个标记接口,实现该接口,不需要重写任何方法
1.6 对象反序列化流
对象反序列化流: ObjectInputStream
ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
构造方法
方法名 | 说明 |
ObjectInputStream(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
反对象序列化方法
方法名 | 说明 |
Object readObject() | 从ObjectInputStream读取一个对象 |
测试类
1 import java.io.*;
2
3 public class OIS {
4 public static void main(String[] args) throws IOException, ClassNotFoundException {
5 File file = new File("F:\\oos.yz");
6 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
7
8 Object j = ois.readObject();
9
10 Student s = (Student) j;
11
12 System.out.println(s.getName()+"\t"+s.getAge());
13 }
14 }
1.7 serialVersionUID&transient
serialVersionUID
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
transient
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
2.Properties集合
2.1 Properties作为Map集合的使用
Properties介绍
是一个Map体系的集合类
Properties可以保存到流中或从流中加载
属性列表中的每个键及其对应的值都是一个字符串
案例
1 import java.util.Properties;
2 import java.util.Set;
3
4 public class Prop {
5 public static void main(String[] args) {
6 Properties prop = new Properties();
7
8 prop.put("1","超人");
9 prop.put("2","蝙蝠侠");
10 prop.put("3","闪电侠");
11
12 Set<Object> keys = prop.keySet();
13 for (Object o : keys){
14 Object value = prop.get(o);
15 System.out.println(value);
16 }
17 }
18 }
2.2 Properties作为Map集合的特有方法
方法名 | 说明 |
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
测试类
1 import java.util.Properties;
2 import java.util.Set;
3
4 public class Prop {
5 public static void main(String[] args) {
6 Properties prop = new Properties();
7
8 prop.setProperty("1","超人");
9 prop.setProperty("2","蝙蝠侠");
10 prop.setProperty("3","闪电侠");
11
12 Set<String> names = prop.stringPropertyNames();
13
14 for (String key : names){
15 String value = prop.getProperty(key);
16 System.out.println(value);
17 }
18 }
19 }
2.3 Properties和IO流相结合的方法
方法名 | 说明 |
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |