疯狂Java学习笔记(020)
一.FileInputStream类
1.FileInputStream类
- 字节输入流操作步骤:
- 创建输入流对象
- 利用流读入数据
- 关闭资源
2.FileInputStream读取数据
- int read( ) //从输入流中读取一个字节
- int read(byte[ ] b) //从输入流中读取字节,放到字节数组中
- int read(byte[ ] b,int off , int len) //从输入流中读取字节,放到字节数组中,只放到指定位置(不常用)
读取操作hi自动把文件指针做想应得移动,如果到达文件得末尾,返回值为-1
3.加上异常处理得完整程序
注意:
- IO操作多数都会抛出异常,声明抛出不是一个好的处理方式
- 注意变量的作用范围,空指针等
4.自动关闭资源的try块
为了替代finall臃肿的写法,JDK7出现了自带关闭资源的try语句块可以不用显示的写finally语句
用法:将需要关闭的资源定义或者初始化语句放到try后的括号里,程序会自动关闭这些资源,前提是这些类实现了AutoCloseable或者Closeable接口
格式:
try(需要自动关闭的资源声明或者初始化){
//正常的逻辑语句
}
注意:如果需要的话,try后依然可以跟catch块和一个finally块
5.文件字节流实现文件复制:单字节复制
思路:
- 使用源文件创建文件输入流对象
- 使用目标文件创建文件输出流对象
- 复制数据
- 关闭资源
- 实现同一个项目路径下的文本文件的复制
- 实现不同路径下的文本文件的复制
- 实现图片的复制
- 实现mp3的复制
6.FileInputStream读取数据标准代码
二、自带缓冲区的字节流
一次读取一个字节数组的数据再效率上提升了很多,字节数组实际上相当与一个缓冲区。
Java提供了自带缓冲区的流,不必自己再定义额外的字节数组充当缓冲区了。
自带缓冲区的字节输入流:
BufferedInputStream
自带缓冲区的字节输出流:
BufferedOutputStream
(一)BufferedOutputStream类
1.BufferedOutputStream类
构造方法:
BufferedOutputStream(OutputStream out) //通过包装一个字节输出流对象,使用默认的大小创建缓冲区流对象
BufferedOutputStream(OutputStream out,int size) //通过包装一个字节输出流对象,使用指定的大小创建缓冲区流对象
包的概念:
2.BufferedOutputStream类
写出数据:
void write(int b) //将一个字节写入缓冲区流
void write(byte[ ] b) //将一个字节数组写入缓冲区
void write(byte[ ] b,int off,int len) //将一个字节数组的一部分写入字节缓冲区流
缓冲区流写入字节示意图
缓冲区数组默认是8192字节
缓冲区流写数据流程,查看源码
void write(int b) //将数据写入到内部的缓冲区中
void write(byte[ ] b,int off,int len) //将字节数组的一部分写到缓冲区中
缓冲区满,或者调用flush方法,或者关闭流,此时把缓冲区中的数据写出到节点流中
(二)BufferedInputStream类
1.BufferedInputStream类构造方法
- BufferedInputStream(InputStream in) //通过包装一个输入流,创建一个带默认缓冲区的字节输入流对象
- BufferedInputStream(InputStream in , int size) //通过包装一个输入流,创建一个带指定缓冲区的字节输入流对象
缓冲区流写入字节示意图
2.BufferedInputStream类
读取数据:
- int read( ) //从缓冲区中读取一个字节
- int read(byte[ ] b) //从缓冲区中读取字节放到一个字节数组中
- int read(byte[ ] b,int off,int len) //从缓冲区照顾你读取字节,存放到数组的指定开始处,并指定读取长度(不常用)
三、测试各种流再复制文件时的效率
FileInputStream
FileOutputStream
基本字节流(节点流):一次读取要给字节,一次读取一个字节数组的数据
BufferedInputStream
BufferedOutputStream
缓冲区流(包装流):一次读取要给字节;一次读取一个字节数组的数据
基本字节流和缓冲字节流复制文件时间:
最慢:普通字节流一次读写一个字节
最快:应该是缓冲字节流一次读写一个字节数组,数组大小需要验证,选择要给最优大小。
----------------------------------------------------------------------------------------------------------------
一、字符流:
1.关于字符流的出现?
一个字符经过编码后可能占用不同的字节数,不是一一对应的关系,使用字节流再操作文本文件的时候不是很方便,不能准确控制到底多少个字节对应一个字符。
所以Java提供了专门用来操作字符的字符流
能准确的从流中 获取/放入 字符
字符流 = 字节流 + 编码方案
二、字符集(编码方案)charSet
ASCii:美国标准委员会制定,用一个字节的7位表示一个字符
ISO8859-1:欧洲,拉丁编码,用一个字节的8位表示一个字符
GBK:中文编码,用两个字节表示一个中文字符
GB2312:GBK的升级版本,拥有更多的字符
GB18030:GBK取代版本,但使用不是很广泛
BIG-5:繁体字的编码
Unicode:国标标准码,绝大多数的字符使用两个字节编码,称为Unicode编码
UTF-8:一种Unicode编码实现方案,当程序中出现的字符需要写到硬盘上的文件,或者通过网络传输时,需要制定编码方案,并由此方案将字符编成具体的字节。
特点:是一种变长的编码方案,编码后的字符有可能占用1-4个字节;英文占一个字节,中文占3个字节。
2.字符串编解码方案示意图
3.字符流继承图
三、转换流:OutputStreamWriter
- 字节流到字符流的一种桥梁,可使用指定的字符集将要写入流中的字符编码成字节
- 操作的数据单位是:字符
- 将对字节的操作转换成对字符的操作
构造方法:
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out,String charsetName) 创建使用指定字符集的OutputStreamWriter
本质上也是一种包装流,读写数据是通过底层的字节流实现的
四、转换流示意图
1.OutputStreamWriter
void write(int b) :写一个字符
void write(String str):写一个字符串
void write(String str,int off ,int len):写一个字符串一部分
void write(char[ ] ch):写一个字符数组
void write(char[ ] ch,int off,int len):写要给字符数组一部分
2.输出字符流的使用步骤:
- 创建字符输出流对象
- 写出数据
- 释放资源
五、转换流:InputStreamReader
从字节流中读取数据,根据指定的字符集解码成字符
构造方法:
InputStreamReader(InputStream in) //用默认字符集创建转换流
InputStreamReader(InputStream in , String charsetName) //用指定字符集创建转换流
读取数据:
int read( ) 读取单个字符
int read(char[ ] ch) 读取字符,并放入一个字符数组
转换流练习:文本文件复制