面试官:你说下对Java IO的理解?
面试官:那要怎么读取字节流?
面试官:你说的这些不是实例,我要的是能真正读取的?
面试官:为什么加一层缓存流就能提高读取效率?
面试官:读取之后呢,我怎么知道文件读取到未尾了?
面试官:那字符流读取呢?
输出流你也讲一讲?面试官:
面试官:那字节流和字符流有什么区别?
面试官:你刚刚提到转换流把字节输入流转换成字符输入流,可不可以倒过来?
面试官:你说下对Java lO的理解?
好的面试官,Java lO有两个参与对象,一个是IO源端,一个是想要和lO源端通信的各种接收端如控制台、文件等,我们程序要保证的就是顺利的读取和顺利的写入。
面试官:那要怎么读取字节流?
读取字节的抽象基类是InputStream,这个基类提供了3个方法可以来读取字节流
1.从输入流读取下一个数据字节,值字节以0到255范围内的int返回
public abstract int read()throws IException
2.从输入流读取一定数量的字节并将它们存储到缓冲区数组b中
public int read(byte bl)throws IException
3.从输入流读取最多len个字节的数据到字节数组中
public int read(byte bl,int off,int len)throwsIOException
面试官:你说的这些不是实例,我要的是能真正读取的?
用抽象基类的子类实现来读取,例如文件流FileInputStream.
new FileInputstream(SOURCE PATH)
我们还可以在外面加一层缓存字节流来提高读取效率
new BufferedInputstream(new FileInputstream(SOURCE PATH))
如果要把缓存流换成字符流来承接,方便使用readLine()读取某一行的话,可以使用转换流把字节输入流转换成字符输入流。
new BufferedReader(new InputstreamReader(new FileInputstream(SOURCE PATH)))
面试官:为什么加一层缓存流就能提高读取效率?
是这样的。因为直接使用 Filelnputstream 读取文件的话,每次调用read都是从磁盘读取一个字节,而每次读取都是一次系统调用。系统调用是操作系统层面的调用,涉及到用户空间和内核空间之间的上下文切换,这些切换是很昂贵的。而如果使用缓存流,一次性从文件里读取多个字节到缓存中,可以减少系统调用同时也减少了磁盘读取,提高了读取的效率
面试官:读取之后呢,我怎么知道文件读取到未尾了?
例如我刚刚说到的字节流基类lnputStream的3个方法,当他们返回-1,就表明输入流到达了未尾
面试官:那字符流读取呢?
字符流的抽象基类是Reader,同样是提供了3个方法来支持字符流读取。
1.读取单个字符。
public int read()throws IOException
2.将字符读入数组。
public int read(char cbuf[])throws IException
3.将字符读入数组的一部分。
abstract public int read(char cbuf[l, int off, int len)I0Exceptionthrows
然后字符流读取的实例是FileReader,同样可以使用缓存字符流提高读取效率
new BufferedReader(new FileReader(new File(SOURCE PATH)))
面试官:输出流你也讲一讲?
好的面试官。
字节输出流的抽象基类是OutputStream,字符输出流的抽象基类是Writer。他们分别提供了以下方法。字节输出流OutputStream:
将指定字节写入此输出流。
public abstract void write(int b)throws IOException
将指定字节数组中的b.ength字节写入此输出流
public void write(byte b[])throws IException
将指定字节数组中从偏移量off开始的len个字节写入此输出流
public void write(byte bl,int off,int len)throws I0Exception
字符输出流Writer:
1.写入单个字符.
public void write(int c)throws I0Exception
2.写入字符数组.
public void write(char cbuf[])throws I0Exception
3.写入字符数组的一部分。
abstract public void write(char cbuf[], int off, int len)throws IoException
另外字符输出流是使用字符来操作数据,所以可以用字符串来代替字符数组,JDK还支持以下入参是字符串的方法。
1.写入一个字符串。
public void write(string str)throws IException
2.写入字符串的一部分。
public void write(string str, int off,int len)throws IoException
面试官:那字节流和字符流有什么区别?
有这些不同之处,主要是3个方面。
基本单位不同。字节流以字节(8位二进制数)为基本单位来处理数据,字符流以字符为单位处理数据。
使用场景不同。字节流操作可以所有类型的数据,包括文本数据,和非文本数据如图片、音频等
而字符流只适用于处理文本数据。
关于性能方面。因为字节流不处理字符编码,所以处理大量文本数据时可能不如字符流高效;而字符流使用到内存缓冲区处理文本数据可以优化读写操作。
面试官:你刚刚提到转换流把字节输入流转换成字符输入流,可不可以倒过来?
JDK没有提供这样的方法。是这样的,虽然字节流比字符流的使用范围更广些,但字符流比字节流操作方便,所以字符流是一个很方便的流了,没有必要把一个方便的流转换成一个不方便的流。
本文使用 文章同步助手 同步