java io nio面试题

java io nio面试题

十二月 11, 2019

一 Java NIO 概览
主要内容:

NIO简介:
Java NIO 是 java 1.4, 之后新出的一套IO接口NIO中的N可以理解为Non-blocking,不单纯是New。

NIO的特性/NIO与IO区别:

1)IO是面向流的,NIO是面向缓冲区的;
2)IO流是阻塞的,NIO流是不阻塞的;
3)NIO有选择器,而IO没有。

读数据和写数据方式:
从通道进行数据读取 :创建一个缓冲区,然后请求通道读取数据。
从通道进行数据写入 :创建一个缓冲区,填充数据,并要求通道写入数据。

NIO核心组件简单介绍
Channels
Buffers
Selectors

二 Java NIO 之 Buffer(缓冲区)
主要内容:
Buffer(缓冲区)介绍:

Java NIO Buffers用于和NIO Channel交互。 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels;
Buffer本质上就是一块内存区;
一个Buffer有三个属性是必须掌握的,分别是:capacity容量、position位置、limit限制。

Buffer的常见方法

Buffer clear()
Buffer flip()
Buffer rewind()
Buffer position(int newPosition)

Buffer的使用方式/方法介绍:

分配缓冲区(Allocating a Buffer):

ByteBuffer buf = ByteBuffer.allocate(28);//以ByteBuffer为例子

写入数据到缓冲区(Writing Data to a Buffer)

写数据到Buffer有两种方法:
1.从Channel中写数据到Buffer
int bytesRead = inChannel.read(buf); //read into buffer.
2.通过put写数据:
buf.put(127);

Buffer常用方法测试
说实话,NIO编程真的难,通过后面这个测试例子,你可能才能勉强理解前面说的Buffer方法的作用。

三 Java NIO 之 Channel(通道)
主要内容:

Channel(通道)介绍

通常来说NIO中的所有IO都是从 Channel(通道) 开始的。
NIO Channel通道和流的区别:

FileChannel的使用
SocketChannel和ServerSocketChannel的使用
️DatagramChannel的使用
Scatter / Gather

Scatter: 从一个Channel读取的信息分散到N个缓冲区中(Buufer).
Gather: 将N个Buffer里面内容按照顺序发送到一个Channel.

通道之间的数据传输

在Java NIO中如果一个channel是FileChannel类型的,那么他可以直接把数据传输到另一个channel。
transferFrom() :transferFrom方法把数据从通道源传输到FileChannel
transferTo() :transferTo方法把FileChannel数据传输到另一个channel

四 Java NIO之Selector(选择器)
主要内容:

Selector(选择器)介绍

Selector 一般称 为选择器 ,当然你也可以翻译为 多路复用器 。它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。
使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。

Selector(选择器)的使用方法介绍

Selector的创建

Selector selector = Selector.open();

注册Channel到Selector(Channel必须是非阻塞的)

channel.configureBlocking(false);
SelectionKey key = channel.register(selector, Selectionkey.OP_READ);

SelectionKey介绍
一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。

从Selector中选择channel(Selecting Channels via a Selector)
选择器维护注册过的通道的集合,并且这种注册关系都被封装在SelectionKey当中.

停止选择的方法
wakeup()方法 和close()方法。

模板代码
有了模板代码我们在编写程序时,大多数时间都是在模板代码中添加相应的业务代码。

客户端与服务端简单交互实例

五  Java NIO之拥抱Path和Files
主要内容
一 文件I/O基石:Path:

创建一个Path
File和Path之间的转换,File和URI之间的转换
获取Path的相关信息
移除Path中的冗余项

二 拥抱Files类:

Files.exists() 检测文件路径是否存在
Files.createFile() 创建文件
Files.createDirectories()和Files.createDirectory()创建文件夹
Files.delete()方法 可以删除一个文件或目录
Files.copy()方法可以吧一个文件从一个地址复制到另一个位置
获取文件属性
遍历一个文件夹
Files.walkFileTree()遍历整个目录

六  NIO学习总结以及NIO新特性介绍

内存映射:

这个功能主要是为了提高大文件的读写速度而设计的。内存映射文件(memory-mappedfile)能让你创建和修改那些大到无法读入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问了。将文件的一段区域映射到内存中,比传统的文件处理速度要快很多。内存映射文件它虽然最终也是要从磁盘读取数据,但是它并不需要将数据读取到OS内核缓冲区,而是直接将进程的用户私有地址空间中的一部分区域与文件对象建立起映射关系,就好像直接从内存中读、写文件一样,速度当然快了。
七 Java NIO AsynchronousFileChannel异步文件通
Java7中新增了AsynchronousFileChannel作为nio的一部分。AsynchronousFileChannel使得数据可以进行异步读写。

  1. 什么是IO流?
    它是一种数据的流从源头流到目的地。比如文件拷贝,输入流和输出流都包括了。输入流从文件中读取数据存储到进程(process)中,输出流从进程中读取数据然后写入到目标文件。

  2. 字节流和字符流的区别。
    字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。

3.Java中流类的超类主要由那些?
java.io.InputStream
java.io.OutputStream
java.io.Reader
java.io.Writer

  1. FileInputStream和FileOutputStream是什么?
    这是在拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)

  2. 字节流和字符流,你更喜欢使用拿一个?
    个人来说,更喜欢使用字符流,因为他们更新一些。许多在字符流中存在的特性,字节流中不存在。比如使用BufferedReader而不是BufferedInputStreams或DataInputStream,使用newLine()方法来读取下一行,但是在字节流中我们需要做额外的操作。

6.System.out.println()是什么?
println是PrintStream的一个方法。out是一个静态PrintStream类型的成员变量,System是一个java.lang包中的类,用于和底层的操作系统进行交互。

7.什么是Filter流?
Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。

  1. 有哪些可用的Filter流?
    在java.io包中主要由4个可用的filter Stream。两个字节filter stream,两个字符filter stream. 分别是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter.这些类是抽象类,不能被实例化的。
    有些Filter流的子类:
    
    LineNumberInputStream 给目标文件增加行号
    DataInputStream 有些特殊的方法如readInt(), readDouble()和readLine() 等可以读取一个 int, double和一个string一次性的,
    BufferedInputStream 增加性能
    PushbackInputStream 推送要求的字节到系统中

9.SequenceInputStream的作用?
这个类的作用是将多个输入流合并成一个输入流,通过SequenceInputStream类包装后形成新的一个总的输入流。在拷贝多个文件到一个目标文件的时候是非常有用的。可用使用很少的代码实现

10.说说PrintStream和PrintWriter
他们两个的功能相同,但是属于不同的分类。字节流和字符流。他们都有println()方法。

  1. 在文件拷贝的时候,那一种流可用提升更多的性能?
    在字节流的时候,使用BufferedInputStream和BufferedOutputStream。
    在字符流的时候,使用BufferedReader 和 BufferedWriter

12 .说说管道流(Piped Stream)

有四种管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.在多个线程或进程中传递数据的时候管道流非常有用。

13.说说File类
它不属于 IO流,也不是用于文件操作的,它主要用于知道一个文件的属性,读写权限,大小等信息。注意:Java7中文件IO发生了很大的变化,专门引入了很多新的类来取代原来的基于java.io.File的文件IO操作方式。详情阅读下面的文章:

Java NIO之拥抱Path和Files

  1. 说说RandomAccessFile?
    它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。 DataInputStream 和 DataOutStream有的方法,在RandomAccessFile中都存在。