一.地位
高,不可或缺。输入输出(I/O)是任何语言都不能避免的问题,java也不例外。
二.本质
操作起来难度相当大。
三.流模型
1.基本概念
- 数据源+目的地。无论是输入还是输出,就是在数据源和目的地之间建立一根管道,数据就像流水一样从数据源流向目的地。
2. Java中谈论输入和输出时,永远站在程序的立场。 - 字节输入流(InputStream)
- 字节输出流(OutputStream)
- 字符输入流(Reader)
- 字符输出流(Writer)
以上四个全是抽象类。
7.选择:
- 字节还是字符:当传输二进制数据的时候选择字节流,当传输文本数据(用记事本可以打开)的时候选择字符流。
- 输入还是输出:相对于程序而言。
- 选择管道:确定另一个端点。
四.分类
- 输入输出
- 字符字节
- 节点流和处理流
- File前缀节点流
- 对象流是处理流(因为没有说目的地是哪)。ObjectOutputStream和ObjectInputStream。
五.操作I/O流类
步骤
- 选取管道(输入还是输出)
- 创建管道(new出来),一定会有编译时异常,所以先把管道赋值为null,否则在finally块中不能关闭。
- 操作管道(输入流–read(),输出流–write()),这两个方法有很多重载,一般用字节数组和字符数组。
- 关闭管道(close()方法)
特例代码,同时完成了输入输出操作,面试中经常出现要手工书写的。复制文件。
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("E:"+File.separator+"input.txt");
out = new FileOutputStream("E:"+File.separator+"output.txt");
int c;
try {
while((c = in.read())!=-1){
out.write(c);
}
} catch (IOException e) {
// TODO: handle exception
System.out.println("在读写文件时,出现异常!");
}
} catch (FileNotFoundException e) {
// TODO: handle exception
System.out.println("系统找不到指定的文件!");
}finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
// TODO: handle exception
System.out.println("关闭不了文件input.txt");
}
}
if(out != null){
try {
out.close();
} catch (IOException e) {
// TODO: handle exception
System.out.println("关闭不了文件output.txt");
}
}
}
大数据量的输入输出时,fout.flush()。因为read(byte[])如果没有
六.对象流—对象的序列化和对象反序列化(重点)
1.特点
- 产生对象的第二种方式
- JavaBean规范之一:应该实现Serializable接口。
- 分布式开发的关键(重量级webService)
- EJB(企业级EnterpriseJavaBean)
- 管道对接。装饰器模式。
2.对象序列化和反序列化
- 对象序列化:将程序中的对象以二进制流的形式输出。ObjectOutputStream。
- 对象反序列化:将输入的二进制流直接转化为程序中的一个对象。ObjectInputStream。
- 至少对接一个节点流才能工作。
3.Serializable:
- Serializable使我们学到的第一个标识接口,不提供任何行为或字段,表示允许进行某类操作,仅此而已。Serializable代表可进行序列化操作。
- 序列化一个对象,除了这个对象本身要实现Serializable接口,这个对象的引用类型属性也要实现Serializable接口。
- 不想让某个属性进行序列化,用transient关键字对属性进行修饰。
- 序列化的类必须和反序列化的类保持一致,不能进行修改(做任何修改都需要重新序列化)。
File类
思考题
为什么字节流的read()的返回是一个int类型。
若用byte来装,有一个有效字节的值就是-1,则不能判断到底是有效字节还是读到末尾。只要使用比byte大的都可以,但当在外部判断时,数字整型常量默认就是int,为了方便,返回就是int。