java nio之channel

简介:   一、通道(Channel):由 java.nio.channels 包定义的。Channel 表示 IO 源与目标打开的连接。Channel 类似于传统的“流”。只不过 Channel本身不能直接访问数据,Channel 只能与Buffer 进行交互。

  一、通道(Channel):由 java.nio.channels 包定义的。Channel 表示 IO 源与目标打开的连接。Channel 类似于传统的“流”。只不过 Channel本身不能直接访问数据,Channel 只能与Buffer 进行交互。

  二、Channel重要实现

  • FileChannel:操作文件的读写
  • SocketChannel:通过TCP读写网络数据
  • ServerSocketChannel:监听TCP连接,你能利用它创建一个最简单的Web服务器
  • DatagramChannel:通过UDP读写网络数据

  三、FileChannel 的文件读写

  1)利用FileChannel 本身提供的transferTo进行数据的读写。

package com.troy.nio.application;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;

public class Channel {

    public static void main(String[] args) throws Exception {
        //读取文件
        FileInputStream fileInputStream = new FileInputStream("d:/t.txt");
        //写出文件
        FileOutputStream fileOutputStream = new FileOutputStream("d:/e.txt");
        //获取读取通道
        FileChannel inChannel = fileInputStream.getChannel();
        //获取写入通道
        FileChannel outChannel = fileOutputStream.getChannel();
        //完成数据的写入
        inChannel.transferTo(0,inChannel.size(),outChannel);
    }
}

  2)利用FileChannel 提供的读写方法

package com.troy.nio.application;

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

public class Channel {

    public static void main(String[] args) throws Exception {
        //读取文件
        FileInputStream fileInputStream = new FileInputStream("d:/t.txt");
        //写出文件
        FileOutputStream fileOutputStream = new FileOutputStream("d:/e.txt");
        //获取读取通道
        FileChannel inChannel = fileInputStream.getChannel();
        //获取写入通道
        FileChannel outChannel = fileOutputStream.getChannel();
        //缓存
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        //读取数据
        while (inChannel.read(byteBuffer) != -1) {
            //转换成可读写
            byteBuffer.flip();
            System.out.println(new String(byteBuffer.array(),"GBK").trim());
            //写出数据,清楚缓存
            outChannel.write(byteBuffer);
            byteBuffer.clear();
        }
    }
}

  四、SocketChannel和ServerSocketChannel在同时使用时,都是tcp协议进行传输的,在使用上面比较服务具体的协议控制

  具体的应用可以参考:http://www.cnblogs.com/ll409546297/p/7929646.html

  五、DatagramChannel的方式

  1)客户端

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class UDPClient {

    public static void main(String[] args) throws Exception {

        //获取UDP通道
        DatagramChannel datagramChannel = DatagramChannel.open();
        //设置非阻塞
        datagramChannel.configureBlocking(false);
        //发送数据
        datagramChannel.send(ByteBuffer.wrap("hello server!".getBytes()),new InetSocketAddress("localhost",9000));
    }
}

  2)服务端的2中写法,阻塞和非阻塞

  1、阻塞

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class UDPServer {

    //UDP通道
    private static DatagramChannel datagramChannel;

    public static void main(String[] args) throws Exception {
        serverInit();
        listen();
    }

    //初始化
    private static void serverInit() throws IOException {
        //获取UDP通道
        datagramChannel = DatagramChannel.open();
        //设置接收端口
        datagramChannel.socket().bind(new InetSocketAddress(9000));
    }

    //监听
    private static void listen() throws IOException {
        while (true) {
            //接收的长度
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            //这里会阻塞
            datagramChannel.receive(byteBuffer);
            byteBuffer.flip();
            System.out.println(new String(byteBuffer.array()).trim());
        }
    }
}

  2、非阻塞,利用selector来进行数据选择

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;

public class UDPServer {

    //选择器
    private static Selector selector;
    //UDP通道
    private static DatagramChannel datagramChannel;

    public static void main(String[] args) throws Exception {
        serverInit();
        listen();
    }

    //初始化
    private static void serverInit() throws IOException {
        //获取选择器
        selector = Selector.open();
        //获取UDP通道
        datagramChannel = DatagramChannel.open();
        //设置非阻塞
        datagramChannel.configureBlocking(false);
        //设置接收端口
        datagramChannel.socket().bind(new InetSocketAddress(9000));
        //注册
        datagramChannel.register(selector, SelectionKey.OP_READ);
    }

    //监听
    private static void listen() throws IOException {
        while (true) {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                if (selectionKey.isReadable()) {
                    //接收的长度
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    //这里不会阻塞
                    datagramChannel.receive(byteBuffer);
                    byteBuffer.flip();
                    System.out.println(new String(byteBuffer.array()).trim());
                }
            }
        }
    }
}

  六、基本上channel的实现用法就这些了,但是里面会涉及到很多细节的用法,这个需要自己进一步研究

 

相关文章
|
1月前
|
存储 Java 数据处理
|
1月前
|
Java API
java中IO与NIO有什么不同
java中IO与NIO有什么不同
|
5天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
2月前
|
移动开发 编解码 网络协议
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
|
2月前
|
网络协议 Java Linux
用Java来实现BIO和NIO模型的HTTP服务器(二) NIO的实现
用Java来实现BIO和NIO模型的HTTP服务器(二) NIO的实现
|
2月前
|
编解码 网络协议 Java
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
|
3月前
|
Java 应用服务中间件 Linux
java中的NIO,BIO,AIO
java中的NIO,BIO,AIO
17 0
|
3月前
|
设计模式 网络协议 Java
Java NIO 网络编程 | Netty前期知识(二)
Java NIO 网络编程 | Netty前期知识(二)
77 0
|
3月前
|
Java 索引
📌 Java NIO Buffer
Java NIO缓冲区在与NIO通道交互时使用。数据从通道读取到缓冲区,然后从缓冲区写入通道。 缓冲区本质上是一块内存,可以在其中写入数据,然后再进行读取。这个内存块被封装在一个NIOBuffer对象中,该对象提供了一组方法,可以更容易地使用内存块。
|
3月前
|
缓存 网络协议 Java
📌 Java NIO Channel
Java NIOChannel和传统的流相似,但是也存在一些差异: • 在同一个Channel通道中,既可以进行 读操作 也可以进行 写操作,但是 流 只能进行 读 或者 写 其中一种操作。 • Channel通道可以进行异步读写。 • Channel可以从 Buffer中进行读写操作。将数据从Channel通道读取到Buffer缓冲区,并将数据从Buffer缓冲区写入Channel通道。