Io流-字节流
Io流概述和分类
- Io:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备中的传输称为流,流的本质是数据传输
- Io流就是用来处理设备间数据传输问题的
常见的应用:文件复制、文件上传;文件下载
分类
- 按照数据的流向
输入流:读数据
输出流:写数据 - 按照数据类型来分
字节流:字节输入流、字节输出流
字符流:字符输入流、字符输出流 - 一般来说,我们说Io流的分类是按照数据类型来分的
- 如果数据通过window自带的记事本软件打开,我们可以读懂里面的内容,就使用字符流,否则使用字节流。
- 字节流是万能流,如果你不知道该使用哪种类型的流,就使用字节流
字节流写数据
字节流抽象基类
- InputStream:这个抽象是表示字节输入流的所有类的超类
- OutputStream:这个抽象类是表示字节输出流的所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
FileOutputStream:文件输出流用于将数据写入File
- FileOutputStream(String name):创建文件输出流以指定的名称写入文件
- 创建字节输出流对象(调用系统功能创建了文件、创建了字 节输出流对象、让字节输出流对象指向创建好的文件)
字节流写数据的三种方式
字节流写数据的两个小问题
字节流写数据然后实现换行呢?
- 不同系统对换行符号的识别是不一样的
- window:\r\n
- linux:\n
- mac:\r
字节流写数据然后实现追加写入呢?
构造方法:
FileOutputStream(String name,boolean oppend):如果第二个参数为true,则将n+1的数据写入文件的末尾而不是开头
注:当我们没有使用该构造方法时,运行多少次都是下划线+10个hello,并不会追加数据
字节流读数据
一次读一个字节数据
FileInputStream(String name):通过打开与实际文件的连接来创建一个,该文件由文件系统的路径名name命名
需求:把文件io.txt中的内容读取出来在控制台输出
一次读一个字节数组数据
需求:把文件io.txt中的内容读取出来在控制台输出
len:是实际读取fis数据的字节个数
new String(byte[] b):通过使用平台的默认字符集解码指定的字节数组来构造新的string 。
注:第三次读取数据时,控制台显示的是
l d \r \n r
这是因为第二次读取的数据是\r \n w o r,存放在bys数组中,实际读取的字节个数是5,而第三次读取时,实际读取的字节个数是4,存放到bys数组中,但是第5个元素r并没有被替换掉
所以我们需要读取要几个就输出几个字节
String (byte[] bytes, int offset, int Length):从索引为offset开始,读取length个字节数据
循环遍历io.txt文件
read(b)与read(byte b)返回值的区别
注:
使用read()方法,返回的值是:读取到的字节码
使用read(byte[] b)方法,返回的值是:读取到的字节码的个数
复制文本文件
需求:把"E:\itheima\javaSE\io.txt"复制到"E:\itheima\io.txt"目录下
分析:复制文本文件,就是吧文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
复制图片
需求:把"E:\itheima\javaSE\软大1904.jpg"复制到"E:\itheima\软大1904.jpg"
字节缓冲流
-
BufferedOutputStream
我们使用FileOutputStream时,写入的每个字节都导致底层系统被调用,而BufferedOutputStream也是可以向FileOutputStream中写数据的,通过设置一个缓冲区,将来我们把这些数据一次性写入FileOutputStream中,即文件中。这样底层调用的次数就变小了,效率就变高了
-
BufferedIntputStream
BufferedInputStream内部有一个缓冲区,默认大小为8M,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快,所以BufferedInputStream的效率很高!
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!这就是inputstream与bufferedinputstream的区别
构造方法
- 字节缓冲输出流:
BufferedOutputStream(OutputStream out) - 字节缓冲输入流:
BufferedInputStream(InputStream in)
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
实例
使用缓存流读取数据时,会先在缓存区查看有没有数据,没有数据再到数据源拿数据,会尽可能的多拿数据。
使用缓存流写数据时,会通过设置一个缓冲区,缓冲区把这些数据一次性写入目的地中