Channel直译就是通道的意思,通道表示对数据源头和数据目标流经途径的抽象描述,和io中的InputStream和OutputStream类似。
首先借用网络上一张Channel的类图:
从channel的类层次结构来看在接口层面有区分读和写两种操作(ReadableByteChannel和WritableByteChannel),这点类似InputStream和OutputStream。但在实现类FileChannel和SocketChannel都实现了读写的接口,也就是既可以从通道中读取数据,又可以写数据到通道,这和io中单向的流是不同的,即nio中的通道是可以双向读写。
从类图中也可以看到nio中几个重要的通道实现:
FileChannel, SocketChannel,ServerSocketChannel, DatagramChannel。
1. FileChannel
文件的读写通道。可从现有的 FileInputStream 、 FileOutputStream 或 RandomAccessFile 对象获得文件通道,方法是调用该对象的 getChannel 方法,这会返回一个连接到相同底层文件的文件通道。
文件通道的状态与其 getChannel 返回该通道的对象密切相关。
在各种情况下指定要求“允许读取操作”、“允许写入操作”或“允许读取和写入操作”的某个实例。
通过 FileInputStream 实例的 getChannel 方法所获得的通道将允许进行读取操作。
通过 FileOutputStream 实例的 getChannel 方法所获得的通道将允许进行写入操作。
如果使用模式 "r" 创建 RandomAccessFile 实例,则通过该实例的 getChannel 方法所获得的通道将允许进行读取操作,如果使用模式 "rw" 创建实例,则获得的通道将允许进行读取和写入操作。
FileInputStream fi = new FileInputStream(infile); FileOutputStream fo = new FileOutputStream(outfile); FileChannel fiChannel = fi.getChannel(); FileChannel foChannel = fo.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (fiChannel.read(buffer) != -1) { buffer.flip(); foChannel.write(buffer); buffer.clear(); } RandomAccessFile raf = new RandomAccessFile(fileName , "rw"); FileChannel fc = raf.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024); mbb.put(0, (byte) 97); mbb.put(1023, (byte) 122);
2. SocketChannel 和 ServerSocketChannel 是对原io包中的 Socket 和 ServerSocket 的可选择的无阻塞通道实现。从类结构来看都实现了SelectableChannel,结合selector实现无阻塞io,Selector为ServerSocketChannel 监控接收客户端连接就绪事件, 为 SocketChannel 监控连接服务器就绪, 读就绪和写就绪事件。
ServerSocketChannel稍微特殊,并没有实现ReadableByteChannel,专门负责监听传入的连接和创建新的 SocketChannel对象.由于ServerSocketChannel没有bind( )方法,因此有必要取出对等的socket并使用它来绑定到一个端口以开始监听连接。
下面一个简单的例子是一阻塞等待请求连接,单线程处理的方式。无阻塞模式要结合Selector事件驱动模型使用。
ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(port)); while(true){ SocketChannel socketChannel = serverSocketChannel.accept(); if(socketChannel != null){ //... } }
结合Selector使用的简单无阻塞模式:
selector = Selector.open(); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(port)); ssc.register(selector, SelectionKey.OP_ACCEPT); while (true) { int selected = selector.select(); if (selected > 0) { Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); selectedKeys.remove(); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel sc = (SocketChannel) key.channel(); IoBuffer buf = IoBuffer.allocate(1024); int readBytes = 0; try { int ret; while ((ret = sc.read(buf.buf())) > 0) { readBytes += ret; if (!buf.hasRemaining()) { break; } } } catch (IOException e) { e.printStackTrace(); } finally { buf.flip(); } // 处理buf中的数据。。。 sc.register(selector, SelectionKey.OP_WRITE); selectedKeys.remove(); } else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { SocketChannel sc = (SocketChannel) key.channel(); String writeInfo = "Server received success !"; sc.write(Charset.forName("UTF-8").encode(writeInfo)); sc.close(); key.cancel(); } } } }
3. DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入,它发送和接收的是数据包。
相关推荐
Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) ...
java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...
JAVA NIO学习资料JAVA NIO学习资料
java nio入门学习,两个pdfjava nio入门学习,两个pdf
java NIO的基本知识点学习笔记,不包含具体代码
05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 10-Java NIO-Channel-...
Java NIO英文高清原版
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...
Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...
java NIO.zip
讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用
java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket
java学习笔记1(java io/nio)设计模式
03-Java NIO-Channel-概述.mp4 04-Java NIO-Channel-FileChannel(介绍和示例).mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 07-Java NIO-Channel-Socket通道-概述...
java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...
javaNIO学习笔记(csdn)————程序
Contents: 1 核心概念以及基本读写 2 缓冲区的实现机制 3 连网与异步IO 4 分散和聚集IO 5 文件锁定
java_nio学习文档
java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...