IO流总结! ! !

IO流

1.异常

1.1异常的分类

Throwable:

​ Error(程序出现的错误,不能使用程序处理,一般无需程序员关注)

​ Exception:

​ 编译时异常:不处理会报错,必须处理(无法预估的用户操作)

​ 运行时异常: 处不处理都一可以,一般是代码写的有问题,自己找问题并修改

异常一定会发生么? 不一定

处理异常的目的: 让代码能够继续运行下去

JVM默认处理方式: 终止程序,打印异常信息

1.2异常的两种处理方式

捕获

1.try…catch(){}

格式:

​ try{

​ //可能出现异常的代码

​ }catch(异常类名 对象名){

​ //对异常的处理

​ }

2.try…catch…finally

格式:

try{

​ //可能出现异常的代码

}catch(异常类名 对象名){

​ //对异常的处理

}finally{

​ //一定会执行的代码

}

注意事项:

  1. catch 块中可以存在多个,并且可以有子父类的关系: 一旦存在子父类的关系,要把子类异常放上面,因为放下面, 就再也执行不到了(catch块中应该写的是一种备选方案)
  2. jdk7:一个catch块中可以处理多个异常,多个异常之间使用| 隔开
  3. try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。
  4. 每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。
  5. 当一个函数的某条语句发生异常时,这条语句的后面的语句不会再执行,它失去了焦点。执行流跳转到最近的匹配的异常处理catch代码块去执行,异常被处理完后,执行完会接着在“处理了这个异常的catch代码块”后面接着执行。
  6. finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

final finalize finally:区别:

​ final: 修饰的类不能被继承,修饰方法不能重写,修饰变量值不变

​ finaliaze: 用于垃圾回收

​ finally: 用于异常处理,代表一定会执行的代码

抛出

格式:

​ 在方法头上: throws 异常类名1,类名2{

​ }

抛给了方法的调用者

1.3异常中常用方法

Trowable

​ getMessage()

​ 获取异常信息,返回字符串。

​ toString()

​ 获取异常类名和异常信息,返回字符串。

​ printStackTrace()

​ 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

​ printStackTrace(PrintStream s)

​ 通常用该方法将异常内容保存在日志文件中,以便查阅。

1.4throw用法

throw不是用来处理异常的,相反是产生一个异常,或者理解成引爆一个异常

格式:

​ 用在方法体中

​ throw 异常对象(只能有一个)

​ throw的异常一定会发生

异常:

throws:作用与方法声明的后面 跟的是异常的类名

throw:作用于方法内部 跟的是异常的对象

自定义异常:

想让自己的类是一个异常类 那么就要继承异常

如果你想要自定义运行时异常 继承RuntimeException

如果你想要自定义编译期异常 继承Exception

1.5自定义异常

定义编译时异常: 继承Exception

定义运行时异常: 继承RuntimeException

1.6异常注意事项

子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

以上异常指的都是编译时异常

2.File

2.1构造方法

public File(String pathname)

public File(String parent,String child)

public File(File parent,String child)

2 .2创建删除重命名

public boolean createNewFile() 创建文件

public boolean mkdir() 创建单层文件夹

public boolean mkdirs() 创建多层文件夹

public boolean delete() 删除文件或文件夹(文件夹中有内容无法删除)

public boolean renameTo(File dest) 文件的重命名(文件的移动)

2.3 File中的判断功能

public boolean isDirectory() 是否是文件夹

public boolean isFile() 是否是文件

public boolean exists() 是否存在

public boolean canRead() 是否可读

public boolean canWrite() 是否可写

public boolean isHidden() 是否隐藏

2.4 基本获取功能

public String getAbsolutePath() 获取绝对路径

public String getPath() 获取相对路径

public String getName() 获取文件名

public long length() 获取文件字节数

public long lastModified() 获取最后修改时间

2.5 高级获取功能

public String[] list() 获取所有子文件名称

public File[] listFiles() 获取所有子文件对象

2.6 过滤器的使用()比较器 迭代器

public String[] list(FilenameFilter filter) 获取所有子文件名称

public File[] listFiles(FilenameFilter filter) 获取所有子文件对象

3.IO流

I: Input: 输入

O: Output: 输出

3.1 文件的本质

存储都是二进制的数据. 我们能够看到数据的具体形态,都是因为各自的软件帮我们做了解码的工作

3.2 字节和字符的区别

字节是存储容量的基本单位,1字节=8个二进制位。

字符是指字母、数字、汉字和各种符号。

一个字符在计算机中用若干个字节的二进制数表示

gbk: 中文: 2个字节 英文/数字: 1个字节

utf8: 中文: 3个字节 英文/数字: 1个字节

计算机中所有的数据能可以使用字节表示

但是只有纯文本文件才能使用字符表示

3.3 读写和输入输出的关系

输入: 读

输出: 写

读进去,写出来

3.4 IO 流的分类

从流向上划分:

​ 输入流 Input

​ 输出流 output

从处理的单位上:

​ 字节流: 以字节为单位进行处理 (任何文件)

​ 字符流: 以字符为单位进行处理 (纯文本文件)

两两组合得到四个基类

​ 字节输入流: InputStream

​ 字节输出流: OutputStream

​ 字符输入流: Reader

​ 字符输出流: Writer

凡是以InputStream 结尾的,都是属于字节输入流

凡是以OutputStream 结尾的,都是属于字节输出流

凡是以Reader 结尾的,都是属于字符输入流

凡是以Writer结尾的,都是属于字符输出流

转换流 负责将字节转成字符 OuputStreamWriter

3.5 FileOutputStream/FileInputStream 用法

FileOutputStream : 文件字节输出流,以字节为单位向文件中写数据

FileOutputStream(File file)

FileOutputStream(String path)

public void write(int b) 写一个字节

public void write(byte[] b) 写一个byte数组

public void write(byte[] b,int off,int len) 写一个数组,从off开始,len个长度

JDK7: 自动关流:

把流的定义语句放到try()中,这样当程序结束后,就可以自动帮我们关流了

在try() 中只能定义流的定义语句 (实现AutoCloseable接口)

FileOutputStream(String path,boolean append)

​ append: 是否追加:

​ true: 如果源文件已存在,且里面有内容,则写入的数据会在原来文件的内容后面继续写

​ false; 如果源文件已存在,且里面有内容,会先将源文件中的内容清空,再写

文件字节流

文件字节输出流用法

构造方法:

​ FileOutputStream(String path); //路径代表写出到哪个文件中

​ File OutputStream(File file);

​ FileOutputStream(String path,boolean append);//append: true: 如果源文件有内容,在内容后追加

​ File OutputStream(File file,boolean append);

成员方法:

​ write(int a); 写一个字节

​ write(byte[] bs); 写一个byte数组

​ write(byte[]bs,int offset,int len); 写一个数组 从off开始 len个长度

文件字节输入流用法

构造方法:

​ FileInputStream(String path); 代表从哪个文件中读取数据

​ FileInputStream(File file);

成员方法:

​ public int read() 每次读取一个字节,并返回

​ public int read(byte[] b) 每次读取一个数组长度的字节,数组存到了数组中,返回真正读取回来的长度

拷贝文件

使用字节流可以拷贝任意文件

流程: 从一个文件中一个一个的读取数组,然后在一个一个的写到文件中

缓冲字节流(高效流)***

为什么要使用缓冲流?

​ 使用字节流每次从文件中进行读写的时候,都需要和文件进行大量的IO交互,与磁盘做交互的效率其实是比较低的,所以为了降低与磁盘的交互次数,可以使用缓冲字节流.缓冲字节流现将数据放到缓存区,我们直接和缓冲区做交互.可以提升效率

缓冲字节输出流

BufferedOutputStream(OutputStream);

flush: 缓冲输出流中特有的方法,将缓冲区中的内容写到文件中

close: 会先调用flush方法,在关流

缓冲字节输入流

BufferedInputStream(InputStream)

BufferedInputStream(InputStream,int size) size: 缓冲区大小,默认8k

拷贝文件

转换流(字符流)***

字符流: **字节流+**编码

编码: 把文字转成二进制

解码: 把二进制转成文件

字符流只能处理纯文本文件(用记事本 打开能看懂)

场景:

​ 可以指定编码

​ 也可以把字节流转成字符流

字符输出流

构造方法:

public OutputStreamWriter(OutputStream out)

public OutputStreamWriter(OutputStream out,String charsetName)

成员方法:

public void write(int c)

public void write(char[] cbuf)

public void write(char[] cbuf,int off,int len)

public void write(String str)

public void write(String str,int off,int len)

字符输入流

构造方法

public InputStreamReader(InputStream in)

public InputStreamReader(InputStream in,String charsetName)

成员方法:

public int read()

public int read(char[] cbuf)

拷贝文件

只能拷贝纯文本文件

简化流(字符流)

不能指定编码,也不能把字节流转成字符流

FileReader/FileWriter

缓冲字符流***

读和写

BufferedWriter

​ void newLine() 一写一行

BufferedReader

​ String readLine() 一读一行

拷贝文件

序列化和对象流

序列化: 将我们的对象转为二进制 然后存储到文件上

反序列化: 从文件上将我们的数据读出来 然后变成我们看得懂的对象的形式

持久化: 把内存数据存储到磁盘上(一般数据库)

实现序列化步骤:

  1. 让类实现Serializable接口
  2. 使用ObjectOutputStream 写数据:调用writeObject
  3. 使用ObjectInputStream 读数据:调用readObject

如果报错: java.io.NotSerializableException: com._51doit.javase06.day17.obj.Person : 检查是否实现Serializable接口:

如果报错:

com._51doit.javase06.day17.obj.Person; local class incompatible:

​ stream classdesc serialVersionUID = 9141174879630663623,

​ local class serialVersionUID = -7794149232825022836

java.io.InvalidClassException: com._51doit.javase06.day17.obj.Person; local class incompatible: stream classdesc serialVersionUID = 6033833087737845462, local class serialVersionUID = 4088506530017170576
​ at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
​ at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630)
​ at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
​ at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
​ at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
​ at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
​ at com._51doit.javase06.day17.obj.ObjectInputStreamDemo.main(ObjectInputStreamDemo.java:11)

由于模板改变导致的:

​ 解决方法:

​ 1, 重写一遍,在读

​ 2, 生成序列化id:

​ 光标放到类名的黄线上,选择两个中的任意一种

Properties配置文件的读取

目的: 便于维护

新建配置文件: 在src右键->new -> file-> config.properties

步骤:

  1. 创建Properties对象
  2. 加载配置文件
  3. 使用对象获取配置文件中的信息

config.properties

date.format=yyyy-MM-dd

标准输入输出流

System.in: InputStream

System.out PrintStream

总结

FileInputStream/FileOutputStream 文件字节流

BufferedInputStream/BufferedOutputStream 缓冲字节流 flush

InputStreamReader/OutputStreamWriter 转换流 把字节流转成字符流, 能够指定编码

FileReader/FileWriter 简化流 不能指定编码

BufferedReader/BufferedWriter 缓冲字符流 newLine/readLine

ObjectInputStream/ObjectOutputStream 对象流 序列化/反序列化 Serialiazable

​ writeObject/readObject

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值