java nio之channel

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

时间: 2024-10-10 22:21:40

java nio之channel的相关文章

java NIO-Channel

基本简介 Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式. Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中. Java NIO: Non-blocking IO(非阻塞IO) Java

Java NIO (2) Channel

Java NIO Channel Java NIO Channels are similar to streams with a few differences: You can both read and write to a Channels. Streams are typically one-way (read or write). Channels can be read and written asynchronously. Channels always read to, or w

java nio之 channel通道(二)

java nio 通道上一篇文章里就讲述过,channel总是写数据的时候,要先把数据写入到bytebuffer,读数据的时候总是要先从channel中读入到bytebuffer.如下图,这个图是好多知名博客常用的图,很好理解这个channel. channel分为一下几种: FileChannel SocketChannel ServerSocketChannel DatagramChannel FileChannel: 经常说的FileChannel都是拿下面的例子说事 代码如下: pack

Java NIO(1)----Channel 和 Buffer

Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API.其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类.因此,在概述中我将集中在这三个组件上.其它组件会在单独的章节中讲到. Channel 和 Buffer 基本上,所有的 IO 在NIO 中都从一个Channel 开始.Channel 有点

Java NIO (5) Channel to Channel Transfers

Java NIO Channel to Channel Transfers In Java NIO you can transfer data directly from one channel to another, if one of the channels is a FileChannel. The FileChannel class has a transferTo() and a transferFrom() method which does this for you. trans

JAVA NIO 之Channel

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.Channel 通道就是将数据传输给 ByteBuffer 对象或者从 ByteBuffer 对象获取数据进行传输. Channel 用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效地传输数据.常用Channel有FileChannel.SocketChannel.DatagramChannel.ServerSocketChannelSocket 可以通过socket 通道的工厂方法直接创建.但是FileChan

JAVA NIO(二)Channel通道

Channel概述 Channel是一个通道,可以通过它读取和写入数据,通道与流的不同之处在于通道是双向的,流是单向的:NIO中通过channel封装了对数据源的操作,通过channel 我们可以操作数据源,但又不必关心数据源的具体物理结构.在大多数应用中,channel与文件描述符或者socket是一一对应的.Channel用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效地传输数据.channel中所有数据都通过 Buffer 对象来处理.您永远不会将字节直接写入通道中

《JAVA NIO》Channel

1.类图 Channle主要分为两类:File操作对应的FIleChannel和Stream操作对应的socket的3个channel.问题:stream操作除了socket还有其他的吧?例如串口等 3.1.1打开通道通道可以以多种方式创建.Socket 通道有可以直接创建新socket 通道的工??方法.但是一个FileChannel 对象却只能通过在一个打开的RandomAccessFile.FileInputStream 或 FileOutputStream对象上调用getChannel(

java NIO中的buffer和channel

缓冲区(Buffer):一,在 Java NIO 中负责数据的存取.缓冲区就是数组.用于存储不同数据类型的数据 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:ByteBufferCharBufferShortBufferIntBufferLongBufferFloatBufferDoubleBuffer 上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区 二.缓冲区存取数据的两个核心方法:put() : 存入数据到缓冲区中get() : 获取缓冲区中的数据