博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java nio之channel
阅读量:7000 次
发布时间:2019-06-27

本文共 5134 字,大约阅读时间需要 17 分钟。

  一、通道(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协议进行传输的,在使用上面比较服务具体的协议控制

  具体的应用可以参考:

  五、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
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的实现用法就这些了,但是里面会涉及到很多细节的用法,这个需要自己进一步研究

 

转载于:https://www.cnblogs.com/ll409546297/p/7941217.html

你可能感兴趣的文章
jvm系列:Java GC 分析
查看>>
深入理解ES6--10.增强的数组功能
查看>>
设计模式在 TypeScript 中的应用 - 观察者模式
查看>>
创业公司小团队为什么要使用Docker
查看>>
异步社区两周年 - 技术图书免费送(活动已结束)
查看>>
Swift 中的 String 和 Substring 如何工作
查看>>
iOS 之 Protocol 协议 委托 代理 详解
查看>>
FMDB 使用方法
查看>>
Git使用笔记
查看>>
初识Scrapy框架+爬虫实战(7)-爬取链家网100页租房信息
查看>>
XXL-CRAWLER v1.1.0 发布了
查看>>
Spring Boot 中使用 Java API 调用 Elasticsearch
查看>>
HTTP/3 来啦,你还在等什么?赶紧了解一下
查看>>
一个合格的Webpack4配置工程师素养:第二部分
查看>>
利用 EasyWeChat 和 ChatterBot 简单搭建一个公众号「自动回复机器人」
查看>>
关于RxJava在业务上的一些思考
查看>>
MySQL8.0 新特性:Partial Update of LOB Column
查看>>
HTTP的历史
查看>>
对称加密、非对称加密、RSA(总结)
查看>>
Java高阶编程——RxBus 开源,基于 RxJava 的 event bus
查看>>