Fork me on GitHub

Java面试题总结二IO流

1.讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
文件流:
FileInputStream/FileOutputStream, FileReader/FileWriter这四个类是专门操作文件流的,用法高度相似,区别在于前面两个是操作字节流,后面两个是操作字符流。它们都会直接操作文件流,直接与OS底层交互。因此他们也被称为节点流。
包装流:
PrintStream/PrintWriter/Scanner,PrintStream可以封装(包装)直接与文件交互的节点流对象OutputStream, 使得编程人员可以忽略设备底层的差异,进行一致的IO操作。因此这种流也称为处理流或者包装流,PrintWriter除了可以包装字节流OutputStream之外,还能包装字符流Writer,Scanner可以包装键盘输入,方便地将键盘输入的内容转换成我们想要的数据类型。
字符串流:
StringReader/StringWriter,这两个操作的是专门操作String字符串的流,其中StringReader能从String中方便地读取数据并保存到char数组,而StringWriter则将字符串类型的数据写入到StringBuffer中(因为String不可写)。
转换流:
InputStreamReader/OutputStreamReader,这两个类可以将字节流转换成字符流,被称为字节流与字符流之间的桥梁。我们经常在读取键盘输入(System.in)或网络通信的时候,需要使用这两个类。
缓冲流:
BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream,没有经过Buffered处理的IO, 意味着每一次读和写的请求都会由OS底层直接处理,这会导致非常低效的问题。经过Buffered处理过的输入流将会从一个buffer内存区域读取数据,本地API只会在buffer空了之后才会被调用(可能一次调用会填充很多数据进buffer)。经过Buffered处理过的输出流将会把数据写入到buffer中,本地API只会在buffer满了之后才会被调用。BufferedReader/BufferedWriter可以将字符流(Reader)包装成缓冲流,这是最常见用的做法。
总结:
FileInputStream/FileOutputStream 需要逐个字节处理原始二进制流的时候使用,效率低下

FileReader/FileWriter 需要组个字符处理的时候使用

StringReader/StringWriter 需要处理字符串的时候,可以将字符串保存为字符数组

PrintStream/PrintWriter 用来包装FileOutputStream 对象,方便直接将String字符串写入文件

Scanner 用来包装System.in流,很方便地将输入的String字符串转换成需要的数据类型

InputStreamReader/OutputStreamReader , 字节和字符的转换桥梁,在网络通信或者处理键盘输入的时候用

BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream , 缓冲流用来包装字节流后者字符流,提升IO性能,BufferedReader还可以方便地读取一行,简化编程。
2.讲讲NIO
1
2
3
4
5
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。
Java NIO: Channels and Buffers(通道和缓冲区),标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
Java NIO: Non-blocking IO(非阻塞IO),Java NIO可以让你非阻塞的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
Java NIO: Selectors(选择器)
Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。
3.String 编码UTF-8 和GBK的区别?
1
2
GBK:GBK是在国家标准GB2312基础上扩容后兼容GB2312的标准(好像还不是国家标准)。GBK编码专门用来解决中文编码的,是双字节的。不论中英文都是双字节的。GBK包含全部中文字符。
UTF-8:UTF-8 编码是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对于英文字符较多的论坛则用UTF-8 节省空间。另外,如果是外国人访问你的GBK网页,需要下载中文语言包支持。访问UTF-8编码的网页则不出现这问题。可以直接访问。UTF-8则包含全世界所有国家需要用到的字符。
4.什么时候使用字节流、什么时候使用字符流?
1
2
3
4
5
字符流:
字符流处理的单元为2个字节的Unicode字符,操作字符、字符数组或字符串,所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,而字符流只能处理字符或者字符串

字节流:
字节流处理单元为1个字节,操作字节和字节数组。字节流可用于任何类型的对象
5.递归读取文件夹下的文件,代码怎么实现
1
2
递归算法是一种直接或间接地调用自身的算法。
栈 主要是用来存放栈帧的,每执行一个方法就会出现压栈操作,所以采用递归的时候产生的栈帧比较多,递归就会影响到内存,非常消耗内存,而使用for循环就执行了一个方法,压入栈帧一次,只存在一个栈帧,所以比较节省内存。