快学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,说实话,你也理解不 ...
随机推荐
- August 20th 2016 Week 34th Saturday
Everything you see exists together in a delicate balance. 你所看到的一切都处于微妙的平衡中. Seeking for balance in l ...
- CSS3混合模式background-blend-mode
注意:background属性中的背景图片和颜色混合,只能在一个background属性中. 属性值: background-blend-mode: normal; //正常 background-b ...
- 柔性数组 data[0]
struct MyData { int nLen; char data[0];}; 在结构中,data是一个数组名:但该数组没有元素:该数组的真实地址紧随结构体MyData之后,而这个地址 ...
- NYOJ题目112指数运算
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAs0AAAIICAIAAAAaCETRAAAgAElEQVR4nO3drW7jWtwv4PcmwnMhxb ...
- JQ AJAX
用AJAX方法不刷新网页使用下拉列表连接数据库 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- ArchLinux 安装笔记 --zz
为何安装 ArchLinux 为了更深层次的理解 Linux (其实只是闲的蛋疼 准备安装介质 U盘首选,没有之一.自己的本子是 MBR 的,UEFI 神马的我才不知道呢哼! 制作 U 盘启动: Li ...
- 【php全局变量和静态变量、静态方法的使用方法】
php全局变量使用关键字global声明,静态变量使用static声明,静态变量的使用可以使用 类名::变量名 示例代码: <?php //全局变量global 的用法和静态变量的使用 glob ...
- AngularJS讲义 - 作用域
什么是作用域? Angular中作用域(scope)是模板以及工作的上下文环境,作用域中存放了应用模型和视图相关的回调行为.作用域是层次化结构的与相关联的DOM结构相对应.作用域可以观察表达式以及传播 ...
- js onclick="return test()"事件返回值,对有些事件,会影响默认动作的执行。如:onclick和onsubmit
onclick="return test()"事件返回值,对有些事件,会影响默认动作的执行.如:onclick和onsubmit <body> <!--事件返回值 ...
- PHP计算程序运行时间的类
<?php class runTime{ private $starTime; private $stopTime; private function getMicTime(){ $mictim ...