快学Java NIO 续篇
可以先看Java NIO的整体介绍,这篇接着说以下内容,《快学Java NIO》续篇
- FileChannel
- SocketChannel
- ServerSocketChannel
- Java NIO DatagramChannel
- Pipe
Java NIO Tutorial 地址:http://tutorials.jenkov.com/java-nio/index.html
Java NIO系列教程译文地址:http://ifeve.com/java-nio-all/
以下是我拜读过程中摘抄的部分内容,并且加了一些内容、笔记,方便以后再翻阅学习
FileChannel
FileChannel是一个连接到文件的通道,可以完成文件读写,总是运行在阻塞模式下。
之前有代码展示如何从文件中读取数据,以下代码展示如何通过channel写文件
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt",
"rw");
FileChannel channel = aFile.getChannel();
String newData = "New String to write to file..." + System.currentTimeMillis();
//如果设置的大小不够存放newData,会抛异常java.nio.BufferOverflowException
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();//limit设置为当前的position,准备读取这个buffer
//FileChannel.write()是在while循环中调用的。
//因为无法保证write()方法一次能向FileChannel写入多少字节
//因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节
while(buf.hasRemaining()) {
channel.write(buf);
}
channel.close();
/**
* 还有如下方法
* channel.size()//该实例关联文件的大小
* channel.truncate() 截取文件,指定长度后的部分将被删除
* channel.force(true);//强制内存数据flush到硬盘
*/
SocketChannel
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道
可以通过以下2种方式创建SocketChannel:
- 打开一个SocketChannel并连接到互联网上的某台服务器。
- 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
从SocketChannel读取数据,写入数据
SocketChannel socketChannel = SocketChannel.open(); //如果设置非阻塞模式,就可以在异步模式下调用connect(), read() 和write()了。可以进一步和Selector配合。之后章节会涉及
//socketChannel.configureBlocking(false);
//这个需要127.0.0.1的9999端口有进程在监听了,之后会将用ServerSocketChannel监听端口,做服务端
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
ByteBuffer buf = ByteBuffer.allocate(48); //剩下的读写都可以参考fileChannel
//非阻塞模式时候可以如下等待
//while(! socketChannel.finishConnect() ){
//wait, or do something else...
//}
//读取数据
int bytesRead = socketChannel.read(buf);
System.out.println(bytesRead);
//写入数据
String newData = "New String to write to file..." + System.currentTimeMillis(); buf.clear();
buf.put(newData.getBytes()); buf.flip(); while(buf.hasRemaining()) {
channel.write(buf);
}
ServerSocketChannel
Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。
阻塞监听模式
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
while(true){
SocketChannel socketChannel =
serverSocketChannel.accept(); //会一直阻塞到有新连接到达
System.out.println("a request receive!");
//do something with socketChannel...
}
非阻塞模式
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);//设置成非阻塞模式 while(true){
SocketChannel socketChannel =
serverSocketChannel.accept(); //没有请求会返回null if(socketChannel != null){
System.out.println("a request receive!");
} }
Java NIO DatagramChannel
Java NIO中的DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。
UDP服务端,监听9999端口
DatagramChannel channel = DatagramChannel.open();
//DatagramChannel可以在UDP端口9999上接收数据包
channel.socket().bind(new InetSocketAddress(9999));
ByteBuffer buf = ByteBuffer.allocate(48); buf.clear();
//receive()方法会将接收到的数据包内容复制到指定的Buffer. 如果Buffer容不下收到的数据,多出的数据将被丢弃 while(true) {
channel.receive(buf);
System.out.println(buf);
buf.clear();
}
UDP客户端,发送数据到服务端
DatagramChannel channel = DatagramChannel.open(); String newData = "New String to write to file..." + System.currentTimeMillis(); ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip(); int bytesSent = channel.send(buf, new InetSocketAddress("127.0.0.1", 9999));
运行服务端后,运行2次客户端,服务端输出
java.nio.HeapByteBuffer[pos=43 lim=48 cap=48]
java.nio.HeapByteBuffer[pos=43 lim=48 cap=48]
Pipe
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
Pipe原理图:

向管道写数据,从管道读数据,这边方便起见就用一个线程读写管道。其实可以用一个线程写管道,另外一个线程读管道,只要他们共享这个pipe对象就行
/*
* 管道是2个线程之间的单向数据连接
*/
public static void main(String[] args) throws IOException {
//创建管道
Pipe pipe = Pipe.open();
Pipe.SinkChannel sinkChannel = pipe.sink();
String newData = "New String to write to file..." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes()); buf.flip(); //往sink Channel里写数据
while(buf.hasRemaining()) {
sinkChannel.write(buf);
} //可以往source Channel读数据
Pipe.SourceChannel sourceChannel = pipe.source(); buf.clear();
int bytesRead = sourceChannel.read(buf);
//read()方法返回的int值会告诉我们多少字节被读进了缓冲区
System.out.println("bytesRead:"+bytesRead);
}
快学Java NIO 续篇的更多相关文章
- 快学Java NIO
Java NIO Tutorial 地址:http://tutorials.jenkov.com/java-nio/index.html Java NIO系列教程译文地址:http://ifeve.c ...
- JAVA NIO之文件通道
1.简介 通道是 Java NIO 的核心内容之一,在使用上,通道需和缓存类(ByteBuffer)配合完成读写等操作.与传统的流式 IO 中数据单向流动不同,通道中的数据可以双向流动.通道既可以读, ...
- 全面解读Java NIO工作原理(1)
全面解读Java NIO工作原理(1) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- Java NIO 基础知识
前言 前言部分是科普,读者可自行选择是否阅读这部分内容. 为什么我们需要关心 NIO?我想很多业务猿都会有这个疑问. 我在工作的前两年对这个问题也很不解,因为那个时候我认为自己已经非常熟悉 IO 操作 ...
- JAVA NIO之浅谈内存映射文件原理与DirectMemory
JAVA类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...
- 【aliyun】学java,看这里,不迷茫!1460道Java热门问题
阿里极客公益活动: 或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里系技术专家来云栖问答为你解答技术难题了 他们用户自己手中的技术来帮助用户成长 ...
- 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!
本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...
- JAVA NIO 内存映射(转载)
原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427 Java类库中的NIO包相对于IO 包来说有一个新功能是内存 ...
- java NIO 随笔
一,NIO入门 NIO 是new io的缩写,说实话,nio api比较难用,所用大家需要采用网络通信的时候,普通首先想到的是netty,不直接使用NIO,但是你不了解NIO,说实话,你也理解不 ...
随机推荐
- a标签的妙用-拨打电话、发送短信、发送邮件
前端时间在做手机WAP网站时,遇到需要点击页面上显示的电话号能直接拨号的需求,查找资料发现可以使用html的a标签完美实现该需求!记录下来以备后用...... 目前主流手机浏览器对H5的支持已经很不错 ...
- Redis内存管理(一)
Redis数据库的内存管理函数有关的文件为:zmalloc.h和zmalloc.c. Redis作者在编写内存管理模块时考虑到了查看系统内是否安装了TCMalloc或者Jemalloc模块,这两个是已 ...
- jvm学习
一.jps主要用来输出JVM中运行的进程状态信息 jps [options] [hostid] 如果不指定hostid就默认为当前主机或服务器. Jps -ml 二.jstack主要用来查看某个Jav ...
- 使用vsphere client 克隆虚拟机
免费的VMWare ESXi5.0非常强大,于是在vSphere5.0平台中ESXi取代了ESX.,使用ESXi经常会遇到这样的问题,我需要建立多个虚拟机,都是windows2003操作系统,难道必须 ...
- SQLServer多表连接查询
双表内部连接查询 select wName,dName from DepartMent,Worker where DepartMent.dID=Worker.did select wName,dNam ...
- 【数据库】 防止sql注入,过滤敏感关键字
private bool FilterIllegalChar(string sWord) { var result = false; var keyWord = @"select|inser ...
- Sublime Text3使用记录
概述 Sublime是一款很好用的程序编辑网站,主要说的就是编写网页代码,同时Sublime支持接口开发,致使网络上有很多大牛写的编辑插件也很多,使用起来也自如方便了好多,最近一直在用Sublime ...
- shell test 數值 字符串 文件比較
數值比較 描述 n1 –eq n2 等於 n1 –gt n2 大於 n1 –ge n2 大於等於 n1 –lt n2 小於 n1 –le n2 小於等於 n1 –ne n2 不等於 字符串比較 ...
- golang channel buffer
package mainimport ( "fmt" "time")func main() { // Case-1: no buffer //chanMessa ...
- 数据结构之图 Part3 – 2 遍历
BFS using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...