转载

Java NIO原理及简单拷贝实列

1、比较

IO NIO
数据处理 字节或字符流(stream) 块(channel)
方向 单向(InputStream/OutputStream) 双向(读写)

2、NIO(Non-blocking I/O), 非阻塞 IO,也可以理解为新IO(new I/O)。相对于传统的IO以字节或字符或单位传输,NIO以数据块的方式批量传输。突出的有点就是快速和简单,在网络传输中优势明显。

3、NIO具有双向读写功能,支持一个缓存中同时包含读写功能。

4、@since jdk1.4

通道Channel

NIO是在IO的基础上集成出来的,而通道channel类似I/O中的流,通过它进行读写操作,且方向是双向的。

通道在包 java.nio.channels 下,主要有以下4种类型

功能 channel for
FileChannel 从文件中读写数据 reading, writing, mapping, and manipulating a file.
DatagramChannel 通过 UDP 读写网络中数据 datagram-oriented sockets.
SocketChannel 通过 TCP 读写网络中数据 stream-oriented connecting sockets
ServerSocketChannel 监听新进来的TCP 连接 stream-oriented listening sockets

缓冲区

IO中缓冲充当装饰类,非必须。而NIO中,一个通道的所有数据必须先放到缓冲区,再进行读写数据,不能直接操作通道进行读写。底层是一个数组。

读写演示

1、为通道新建一个8个字节缓冲区,则最大容量 capacity 为8,还可以读写的字节数 limit 也为8,

指针 posistion 指向下一个待读写的位置,即当前已经读写的字节数。

Java NIO原理及简单拷贝实列

2、从输入通道中读取 4个字节数据写入缓冲区,posittion指针指向下一个位置4,limit不变。

Java NIO原理及简单拷贝实列

3、将缓冲区写入输出通道,先调用 flip() ,该方法flip缓存,limit设置到当前position位置,并且limit标记到4,然后position设置为0。

Java NIO原理及简单拷贝实列

4、从缓冲区中取 4 个字节到输出缓冲中,此时 position 设为 4。

Java NIO原理及简单拷贝实列

5、最后需要调用 clear() 方法,该方法清空缓存,position设置到0,limit设置到capacity。

Java NIO原理及简单拷贝实列

代码演示

使用nio,从d盘中的aaa.txt文件拷贝到e盘。

public class TestNIO {

    @Test
    public void testCopy(){
        try {
            // 创建输入流
            FileInputStream in = new FileInputStream("D://aaa.txt");
            // 创建输入通道
            FileChannel inChannel = in.getChannel();
            // 创建输出流
            FileOutputStream out = new FileOutputStream("E://aaa.txt");
            // 创建通道
            FileChannel outChannel = out.getChannel();
            // 创建缓存,大小1024字节
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            // 循环读写
            while (true){
                // 从通道读取序列的自接到给定缓冲区,更新position位置
                int read = inChannel.read(buffer);            
                // 全部读完退出
                if (read==-1){
                    break;
                }   
                // flip缓存,position回到0
                buffer.flip();
                // 缓冲区写道输出通道
                outChannel.write(buffer);
                // 清空,limit回到capacity
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制代码

拷贝完成!

原文  https://juejin.im/post/5cb953fee51d456e6479b470
正文到此结束
Loading...