最近项目中有用到io流,由于这部分基础不牢,所以重新学习。
介绍
什么是io流?
流的分按两种方式进行分类:
- 以流的方向进行分类
我们的文件保存在硬盘上,从硬盘到内存的过程,叫做输入(Input)。
从内存到硬盘上的过程,叫做输出(Output)。
- 按照读取数据的不同进行分类
有的流是按照字节的方式读取数据。一次读取1个字节的byte。等同于一次读取8个二进制位。这种流式万能的,什么都可以读取,文件、图片、音乐...
有的流式按照字符的方式读取数据的。但是只能读取普通的纯文本文件,word文件也无法读取!当读取纯文本文件时,每次都读取一个字符,不管是中文还是英文都读取一个字符。而如果按字节流,中文一个字要读取两遍才可以。
我们需要注意,java中的char字符底层是占用两个字节的,而一个英文字母在windows中是占用一个子杰,但是在java中就是一个char。
综上所述
- 输入流、输出流
- 字节流、字符流
四大家族
四个抽象类:
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
四个抽象类都实现了java.io.Closeable,都有close方法, 我们在使用的时候,应该养成一个良好的习惯,流毕竟是一个通道(内存与硬盘的通道),所以我们在使用结束后一定要关闭,不然就会占用很多资源。
同时,我们需要知道所有的输出流都实现了java.io.Flushable接口,都是可以刷新的,都含有flush方法。养成好习惯,我们输出流在最终输出之后,一定要使用flush进行刷新下,表示当前管道的未输出的数据强行输出完,这样可以保证我们的的数据不会丢失!
另外:在java中,以stream结尾的class都是字节流。以Reader/Writer结尾的都是字符流。
FileInputStream
- 文件字节的输入流,万能的,任何类型的文件都可以按照这个流进行读取。
- 字节的方式,完成输入的操作,完成读的操作。
/**
* @author szw<szw0814 @ 1 6 3 . com> 2020/11/29
*/
public class FileInputStreamTest {
@Test
public void readFile(){
FileInputStream f = null;
try {
f = new FileInputStream("E:\\test.txt");
int read = f.read();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
f.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上的代码需要注意几个问题:
- 在new FileInputStream时有参构造中填写的是文件位置,可以是相对路径,也可以是绝对路径。
- 相对路径是相对与该项目
- 路径中如果含有‘\’字符,需要进行转义,如果是‘/’,则不需要
- 一次read只能读取一个字符,读到结束时,会返回-1
/**
* @author szw<szw0814 @ 1 6 3 . com> 2020/11/29
*/
public class FileInputStreamTest {
@Test
public void readFile(){
FileInputStream f = null;
try {
f = new FileInputStream("E:\\test.txt");
byte[] bytes = new byte[4];
int readCount = 0;
while ((readCount = f.read(bytes)) != -1){
System.out.print(new String(bytes,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
f.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们知道,String类型的底层就是char数组,我们可以进行通过char数组new String类型。
f.readCount返回的是读取的长度。当读取长度为-1时就代表读取到末尾了。
补充两个方法
int available(); // 返回流中当前有多少没有读取到的字节数量
long skip(long n); // 跳过几个字节不读
我们在刚刚的案例中是创建一个长度为4的char数组,其实我们有了available方法,我们就可以直接拿到数组的大小,但是注意文件不可以很大。
网友评论