API(IO流)

1、概念和三要素

1)一套用于数据传输的机制
2)根据传输的方向(根据内存当作参照物):输入流—从外部往内存来传输数据 输出流—从内存往外来传输数据
3)根据数据表现形式:字节流—底层以字节流来传输数据、字符流—底层以字符来传输数据
四大基本流(对应的四个类都是抽象类)
字符输出流(Writer)、字符输入流(Reader)
字节输出流(OutputStream)、字节输出流(InputStream)
4)传输场景(数据存放/获取的位置)
硬盘、内存、网络、外设

2、硬盘

2.1 字符流

2.1.1 FileWriter(文件字符输出流)

1)FileWriter writer=new FileWriter(“D:\a.txt”);
①创建文件字符输出流对象。
②在创建对象过程中会检测路径信息是否存在,如果不存在就会自动创建空文件(保证可以正常的写出数据到指定位置)
③如果路径信息已经存在且对应的文件有内容还是创建空文件进行覆盖是为了避免之前文件的内容对之后的写出的内容造成干扰。
2)writer.write(“good”);
①写出数据。
②底层把数据存放到缓冲区来进行传输数据。
③为了保证传输的效率规定缓冲区只有存满才传输。
④如果给定的数据没有存满缓冲区,所以数据滞留在缓冲区没有传输过去。
3)writer.flush();
冲刷缓冲区—无论缓冲区是否存满都可以进行数据传输
4)writer.close();
①关流(关闭传输通道 自带冲涮缓冲区功能)
②防止数据滞留在缓冲区
5)writer=null;
把对象置为null值(让对象变为无用对象等待系统进行垃圾回收)

2.1.2 FileReader(文件字符输入流)

没有缓冲区的

1)FileReader reader=new FileReader(“D:\1.txt”);
①创建文件字符输入流对象
②底层没有缓冲区
2)reader.read();
①读取数据
②read无参方法返回的是读取到的一个字符对应的编码值。
③读取结束的条件是-1。
3)通过for循环实现
4)reader.close();
关流

自定义缓冲区

1)FileReader reader=new FileReader(“D:\1.txt”);
创建文件字符输入流对象
2)char[] cs=new char[5];
定义数组来代表缓冲区
3)int len=-1;
while ((len=reader.read(cs))!=-1)
①把读取到的字符放到数组中,读取结束的条件是返回-1
②返回值就是读取到字符个数
4) System.out.println(new String(cs,0,len));
①while循环里可以把每次读取到数组中的内容来进行展示
②调用String类的有参构造把字符数组内容转成新的字符串对象
5)reader.close();
关流

2.2字节流

2.2.1 FileOutputStream(文件字节输出流)

1)FileOutputStream fos=new FileOutputStream(“D:\123.txt”,true);
①创建文件字节输出流对象
②底层没有缓冲区
③append的值默认是false表示不追加,给定true可以追加数据
2)fos.write(“good”.getBytes());
写出数据
3)fos.close();
关流

2.2.2 FileInputStream(文件字节输入流)

1)FileInputStream fis=new FileInputStream(“D:\3.txt”);
①创建文件字节输入流对象
②底层没有缓冲区
2)fis.read()
①读取数据
②read无参方法只能每次获取一个字节对应的编码值
③读取结束的条件是-1
3)自建缓冲区
byte[] bs=new byte[3];
int len=-1;
while ((len=fis.read(bs))!=-1){
System.out.println(new String(bs,0,len));
}
4)fis.close();
关流

2.3 缓冲流

给其他流来提供缓冲区

2.3.1 BufferdReader

1)BufferedReader br=new BufferedReader(new FileReader(“D:\a.txt”));
①创建缓冲流的对象
②底层数据还是被文件字节输入流对象来做数据传输,缓冲流对象只是提供缓冲区来提高传输的效率
③装饰者设计模式(同类对象给本类对象增强功能)
2)br.readLine()
①读取一行内容
②读取结束的条件是返回null值
3)循环实现

2.3.2 BufferedWriter

1)BufferedWriter bw=new BufferedWriter(new FileWriter(“D:\b.txt”));
①创建缓冲流对象
②底层还是根据文件字符输出流来写数据,缓冲流只是来提高传输的效率
③缓冲流是给文件字符输出流提供一个更大的缓冲区
2) bw.write(“123”);
写出数据
3)bw.newLine();
bw.write(“abc”)
换行
Windows换行符—\r、\n;
Linux换行符—\n
4)bw.close();
关流

补充:

1)模式:遇到统一问题给出的解决方式
2)设计模式:在软件开发过程中,遇到的统一问题给出的统一解决方案
3)装饰者设计模式:本类对象给同类对象增强功能或者完善功能

IO流的异常捕获

1.在try块外声明流对象并赋值为null值,真正的初始化在try块里
2.保证流对象只有初始化成功才能进行正常的关流
3.无论关流成功与否都要把流对象置为null值等待系统进行垃圾回收
4.关流中包含自动冲刷,如果关流失败发生在自动冲刷之前就有可能导致数据滞留在缓冲区,需要手动冲刷

2.4 系统流

1、out、err、in(都是静态的字节流对象)
2、系统流使用完毕不能关流
eg:in是静态对象,全局共享同一个静态对象,如果关闭流通道。那么其他地方在使用的键盘录入都会关闭。

2.5 转换流(实现字节流和字符流的相互转换)

2.5.1 OutputStreamWriter—字符流转成字节流

①创建转换流对象
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(“D:\1.txt”));
②底层真正做数据传输的是文件字节输出流
③首先自动提供字符流来存放字符形式的数据再根据底层文件字节流来做数据传输
//写出数据
//首先要准备数据—字符形式的数据—只能自动提供字符流来存放字符形式的数据
osw.write(“上午好”);
④转换流—字符流转成字节流
⑤关流
osw.close();

2.5.2 InputStreamReader—字节流转成字符流

①创建转换流对象
InputStreamReader isr=new InputStreamReader(new FileInputStream(“D:\3.txt”));
②底层是根据文件字节输入流来传输数据
③首先根据文件字节输入流来读取数据,再是自动提供字符流来展示字符形式的数据
//读取数据
int len=-1;
char[] cs=new char[10];
//展示数据的形式是字符形式的数据—自动提供字符流来接收
while ((len=isr.read(cs))!=-1){
System.out.println(new String(cs,0,len));
}
④转换流是把字节流转成字符流
⑤关流
isr.close();

注:

可以指定码表

2.6 序列化与反序列化

2.6.1序列化

把对象以及相关的信息转成字节数组
把字节数组内容最终存储在硬盘中—持久化(序列化是前提)
1)创建对象
路径信息没有指定盘符就是存放在当前工程里
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(“p.data”));
2)提供对象
Person p=new Person();
p.setName(“lili”);
p.setAge(18);
3)序列化—对象转成字节信息
oos.writeObject( p );
4)关流
oos.close();

2.6.2 反序列化

把字节数组转成对应的对象
1)创建对象
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(“p.data”));
2)反序列化—把字节数组转成对象
读取文件里的字节信息转成对象
Person p= (Person) ois.readObject();
3)关流
ois.close();
4)展示数据
System.out.println(p.getName()+","+p.getAge());

2.6.3 注意

1、类实现Serializable接口产生的对象才支持序列化
2、可以把属性序列化过去但是不能序列化方法
3、被static修饰的属性或者被transient修饰的属性不能序列化过去
4、serialVersionUID—序列化版本号
在序列化之前会根据当前类的属性和方法计算出一个序列化版本号,这个版本号会随着对象信息一起序列化过去。在反序列化之前再次根据当前类的属性和方法计算出一个版本号,拿着两个版本号来进行比较如果相同则
反序列化成功如果不相同则反序列化失败。可以通过自定义设置serialVersionUID指定了版本号就不会再去计算版本号就可以保证前后版本号一致。
5、集合和映射的对象都不能直接进行序列化,只能依次遍历集合或者映射来序列化集合或者映射的元素对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值