一、IO流概述
说到IO流,先得提一提电脑的基本概念:
CPU:中央处理器,处理速度最快。memory:内存,临时性存储设备,处理速度次之,但数据不保存。disk:硬盘,持久性存储设备,处理速度最慢,但数据永久保存。什么叫IO流?
IO流,就是指读写文件的技术。
1.input
I就是指input:输入的意思,这是输入流。
意思是将硬盘里的数据输入到内存里,也就是读取文件。
2.output
O指output:输出的意思,这是输出流。
意思是将内存中的数据输出到硬盘上,也就是写入文件。
用一句话记忆就是:输入到内存(读取硬盘),从内存输出(写入硬盘)。
举一个例子:
我们在记事本上写东西,写完后保存,保存的过程就是写入文件的过程。
不保存:数据是在内存里面,退出后数据会消失;保存:数据会被写到硬盘上,退出后数据也会保存。其中根据数据的类型IO流又分为:
字节流:以字节为单位读写数据的流,能够操作所有文件
字节输入流: InputStream字节输出流: OutputStream字符流 :以字符为单位读写数据的流,用于操作文本文件
字符输入流: Reader字符输出流: Writer今天主要学习字节流:
二、OutputStream输出流
它是输出流最上层的父类,是一个抽象类,其中它有一个子类叫FileOutputStream。
1.构造方法(一)
先介绍其两个构造方法:
①构造方法一:路径存在
FileOutputStream(String name)。
根据文件路径输出文件,“a.txt”是一个相对路径,所以是输出在当前项目下。
②构造方法一:路径不存在
“aa/a.txt”因为其父路径不存在,所以会报错。
③构造方法二
FileOutputStream(File file)。
一般都是使用构造方法一,简单方法,只要输入路径就好了,但是会出现②中的这种情况。
而构造方法二就是解决这类问题的。
可以先在file中加一个判断,父路径不存在就先创建目录,再创建输出流。
2.常用方法
①write(int b)方法
这个方法表示是一个字节一个字节地写。
按照ASCII码表编码,97就对应a,98就对应b,99就对应c。
所以①的操作会在文件里写入abc。
②write(byte[] b)方法
这是先写一个byte数组,在写入文件。
也是按照ASCII码表编码。
③write(byte[] b, int off, int len)
off表示的是偏移量
len表示的是长度
也就是说写入文件的数组,是从b数组中off索引位开始,2个长度。
④close()方法
关流,节省资源。就可以将其理解成关闭水龙头。
所以在a.txt文件中会写入:abcabcbc。
3.构造方法(二)
我们新创建一个输出流,操作同一个文件,写入一个数组,会将文件中的内容覆盖掉。
a.txt文件里的内容从abcabcbc变成了刘小爱。
但若是我不是想覆盖而是续写在后面该怎么办?
4.构造方法(三):
FileOutputStream(String name,boolean append)
append,附加的意思,默认值为false。
如果append为true的话,会拼接到文件后面;如果append为false的话,就会覆盖。
①直接输入换行符
不同的操作系统有着不同的换行符
Windows 系统识别的换行符:\r\nUnix 系统识别的换行符:\nMacOs/Linux系统识别的换行符:\r②System方法输入换行符
System.lineSeparator():该方法会根据系统的不同而输入不同的换行符。
二、InputStream输入流
它是输入流最上层的父类,是一个抽象类,其中它有一个子类叫FileInputStream。
1.read方法基本用法
①创建输入流
如果文件不存在,输入流会直接报错。
②read()方法
输入流的读操作。
返回值即为读取的字符,一次只能读取一个;如果读到了文件末尾,返回值为-1。③使用while循环
一次读取所有内容,当返回值为-1时结束循环。
2.read方法(利用buffer读取文件)
这个稍稍有点难理解,我们一步一步分析:
①创建一个输入流
其中文件里的内容为abcdefgh.
创建buffer数组,长度为3,(buffer为缓存的意思)
②第一次读数据
将读到的数据放入buffer中,并返回读到的长度。
因为buffer的长度为3,所以每次读取读3个字节。
所以读到的是abc,长度为3。
③第二次读数据
读到的是def,长度为3。
buffer中def将abc覆盖掉了,所以打印def。
④第三次读数据
文件中只有最后两个字节了,
所以读到的是gh,长度为2
buffer中只覆盖了前两个字节,后面的第3个字节保持不变(gh将def覆盖得到ghf),所以打印ghf。
⑤第四次读数据
因为都读完了,根本就没有读文件,所以返回值为-1(注意不为0哦)
buffer没有改变,所以还是打印ghf。
以上就是利用buffer数组读取文件时的工作原理。
但这样太繁琐了,有没有简单的方法?
有的,使用while循环就好了。
3.read方法(while循环)
①使用while循环
当length不为-1时,一直循环执行read操作;
当length为-1时,表示文件读到了最后,所以结束循环。
②使用字符串偏移
最后一次的字符串长度我们只需要读取到的数据,也就是ghf只需要gh即可。