Java NIO深入理解Channel(通道)

前言

Github:https://github.com/yihonglei/java-all

Project:java-nio

一 Channel概述

通道Channel由java.nio.channels包定义。Channel表示IO源与目标打开的连接。

Java NIO的通道类似流,Channel本身不能直接访问数据,Channel只能与Buffer进行交互。

既可以从通道中读取数据,又可以写数据到通道,通道可以异步地读写。

通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

即从通道读取数据到缓冲区,从缓冲区写入数据到通道。如下图所示:

Java NIO深入理解Channel(通道)_第1张图片

 

二 Channel的实现

如下是Java NIO中最重要的通道的实现。

FileChannel

从文件中读写数据。

DatagramChannel

能通过UDP读写网络中的数据。

SocketChannel

能通过TCP读写网络中的数据。

ServerSocketChannel

可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

三 Channel实例

通过Java NIO复制文件实例。

package com.lanhuigu.nio.channel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 基于NIO完成文件复制
 *
 * @author yihonglei
 */
public class ChannelCopyFileTest {
    public static void main(String[] args) {
        // 源文件
        File fromFile = new File("/Users/yihonglei/tmp/hello.txt");
        // 目标文件
        File toFile = new File("/Users/yihonglei/tmp/hello-copy.txt");
        try (
                // 根据源文件创建文件输入流
                FileInputStream fis = new FileInputStream(fromFile);
                // 根据目标文件创建文件输入流,如果文件不存在,自动创建
                FileOutputStream fos = new FileOutputStream(toFile);

                //1、获取通道
                FileChannel inChannel = fis.getChannel();
                FileChannel outChannel = fos.getChannel();
        ) {
            // 2、分配指定大小缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(48);

            // 3、将通道的数据读取到缓冲区
            while (inChannel.read(buffer) != -1) {
                // 切换模式
                buffer.flip();

                //4、从缓冲区写入到通道
                outChannel.write(buffer);

                //5、清空缓冲区
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意 buf.flip() 的调用,首先读取数据到Buffer,然后反转Buffer,接着再从Buffer中读取数据

你可能感兴趣的:(#,---NIO)