在
JDK 1.4
以前,
Java
的
IO
操作集中在
java.io
这个包中,是基于流的阻塞(
blocking
)
API
。对于大多数应用来说,这样的
API
使用很方便,然而,一些对性能要求较高的应用,尤其是服务端应用,
往往需要一个更为有效的方式来处理
IO
。从
JDK 1.4
起,
NIO
API
作为一个基于缓冲区,并能
提供非阻塞
(non-blocking)IO
操作的
API
被引入。本文对其进行深入的介绍。
NIO API
主要集中在
java.nio
和它的
subpackages
中:
java.nio
定义了
Buffer
及其数据类型相关的子类。其中被
java.nio.channels
中的类用来进行
IO
操作的
ByteBuffer
的作用非常重要。
java.nio.channels
定义了一系列处理
IO
的
Channel
接口以及这些接口在文件系统和网络通讯上的实现。通过
Selector
这个类,还提供了进行非阻塞
IO
操作的办法。这个包可以说是
NIO API
的核心。
java.nio.channels.spi
定义了可用来实现
channel
和
selector API
的抽象类。
java.nio.charset
定义了处理字符编码和解码的类。
java.nio.charset.spi
定义了可用来实现
charset API
的抽象类。
java.nio.channels.spi
和
java.nio.charset.spi
这
两个包主要被用来对现有
NIO API
进行扩展,在实际的使用中,我们一般只和另外的
3
个包打交道。下面将对这
3
个包一一介绍。
Package java.nio
这个包主要定义了
Buffer
及其子类。
Buffer
定义了一个线性存放
primitive
type
数据的容器接口。对于除
boolean
以外的其他
primitive type
,都有一个相
应的
Buffer
子
类,
ByteBuffer
是其中最重要的一个子类。
下面这张
UML
类图描述了
java.nio
中的类的关系:
Buffer
定义了一个可以线性存放
primitive
type
数据的容器接口。
Buffer
主要包含了与类型(
byte, char…
)无关的功能。值得
注意的是
Buffer
及其子类都不是线程安全的。
每个
Buffer
都有以下的属性:
capacity
这个
Buffer
最多能放多少数据。
capacity
一般在
buffer
被创建的时候指定。
limit
在
Buffer
上进行的读写操作都不能越过这个下标。当写数据到
buffer
中时,
limit
一般和
capacity
相等,当读数据时,
limit
代表
buffer
中有效数据的长度。
position
读
/
写操作的当前下标。当使用
buffer
的相对位置进行读
/
写操作时,读
/
写会从这个下标进行,并在操作完成后,
buffer
会更新下标的值。
mark
一个临时存放的位置下标。调用
mark()
会将
mark
设为当前的
position
的值,以后调用
reset()
会将
position
属性设置为
mark
的值。
mark
的值总是小于等于
position
的值,如果将
position
的值设的比
mark
小,当前的
mark
值会被抛弃掉。
这些属性总是满足以下条件:
0 <= mark
<= position
<= limit
<= capacity
limit
和
position
的值除了通过
limit()
和
position()
函数来设置,也可以通
过下面这些函数来改变:
Buffer clear()
把
position
设为
0
,把
limit
设为
capacity
,一般在把数据写入
Buffer
前调用。
Buffer flip()
把
limit
设为当前
position
,把
position
设为
0
,一般在从
Buffer
读出数据前调用。
Buffer rewind()
把
position
设为
0
,
limit
不变,一般在把数据重写入
Buffer
前调用。
Buffer
对象有可能是只读的,这时,任何
对该对象的写操作都会触发一个
ReadOnlyBufferException
。
isReadOnly()
方法可以用来判断一个
Buffer
是否只读。
ByteBuffer
在
Buffer
的子类中,
ByteBuffer
是一个地位较为特殊的类,因为在
java.io.channels
中定义的各种
channel
的
IO
操作基本上都是围绕
ByteBuffer
展开的。
ByteBuffer
定义了
4
个
static
方法来做创建工作:
ByteBuffer allocate(int capacity)
创建一个指定
capacity
的
ByteBuffer
。
ByteBuffer allocateDirect(int capacity)
创建一个
direct
的
ByteBuffer
,这样的
ByteBuffer
在参与
IO
操作时性能会更好(很有可能是在底层的实现使用了
DMA
技术),相应的,创建和回收
direct
的
ByteBuffer
的代价也会高一些。
isDirect()
方法可以检查一个
buffer
是否是
direct
的。
ByteBuffer wrap(byte [] array)
ByteBuffer wrap(byte [] array, int offset, int length)
把一个
byte
数组或
byte
数组的一部分包装成
ByteBuffer
。
ByteBuffer
定义了一系列
get
和
put
操作来从中读写
byte
数据,如下面几个:
byte get()
ByteBuffer get(byte [] dst)
byte get(int index)
ByteBuffer put(byte b)
ByteBuffer put(byte [] src)
ByteBuffer put(int index, byte b)
这些操作可分为绝对定位和相对定为两种,相对定位的读写操作依靠
position
来定位
Buffer
中的位置,并在操作完成后会更
新
position
的
值。
在其它类型的
buffer
中,也定义了相同的函数来读写数据,唯一不同的就是一些参数和返回值的类型。
除了读写
byte
类型数据的函数,
ByteBuffer
的一个特别之处是它还定义了读写其它
primitive
数据的方法,如:
int getInt()
从
ByteBuffer
中读出一个
int
值。
ByteBuffer putInt(int value)
写入一个
int
值到
ByteBuffer
中。
读写其它类型的数据牵涉到字节序问题,
ByteBuffer
会按其字节序(大字节序或小字节序)写入或读出一个其它类型的数据(
int,long…
)。字节序可以用
order
方法来取得和设置:
ByteOrder order()
返回
ByteBuffer
的字节序。
ByteBuffer order(ByteOrder bo)
设置
ByteBuffer
的字节序。
ByteBuffer
另一个特别的地方是可以
在它的基础上得到其它类型的
buffer
。如:
CharBuffer asCharBuffer()
为当前的
ByteBuffer
创建一个
CharBuffer
的视图。在该视图
buffer
中的读写操作会按照
ByteBuffer
的字节序作用到
ByteBuffer
中的数据上。
用这类方法创建出来的
buffer
会从
ByteBuffer
的
position
位置开始到
limit
位置结束,可以看作是这段数据的视图。视图
buffer
的
readOnly
属性和
direct
属性与
ByteBuffer
的一致,而且也只有通过这种方法,才可以得到其他数据类型的
direct buffer
。
ByteOrder
用来表示
ByteBuffer
字节序的类,可将其看成
java
中的
enum
类型。主要定义了下面几个
static
方法和属性:
ByteOrder BIG_ENDIAN
代表大字节序的
ByteOrder
。
ByteOrder LITTLE_ENDIAN
代表小字节序的
ByteOrder
。
ByteOrder nativeOrder()
返回当前硬件平台的字节序。
MappedByteBuffer
ByteBuffer
的子类,是文件内容在内
存中的映射。这个类的实例需要通过
FileChannel
的
map()
方法来创建。
接下来看看一个使用
ByteBuffer
的例子,这个例子从标准输入不停地读入字符,当读满一行后,将收集的字符写到标准输出:
public
static
void
main(String
[]
args)
throws
IOException
{
//
创建一个
capacity
为
256
的
ByteBuffer
ByteBuffer
buf
=
ByteBuffer.allocate(256);
while
(
true
)
{
//
从标准输入流读入一个字符
int
c
=
System.in.read();
//
当读到输入流结束时,退出循环
if
(c
==
-1)
break
;
//
把读入的字符写入
ByteBuffer
中
buf.put((
byte
)
c);
//
当读完一行时,输出收集的字符
if
(c
==
'\n'
)
{
//
调用
flip()
使
limit
变为当前的
position
的值
,position
变为
0,
//
为接下来从
ByteBuffer
读取做准备
buf.flip();
//
构建一个
byte
数组
byte
[]
content
=
new
byte
[buf.limit()];
//
从
ByteBuffer
中读取数据到
byte
数组中
buf.get(content);
//
把
byte
数组的内容写到标准输出
System.out.print(
new
String(content));
//
调用
clear()
使
position
变为
0,limit
变为
capacity
的值,
//
为接下来写入数据到
ByteBuffer
中做准备
buf.clear();
}
}
}
|
Package
java.nio.channels
这个包定义了
Channel
的概念,
Channel
表现了一个可以进行
IO
操作的通道(比如,通过
FileChannel
,我们可以对文件进行读写操作)。
java.nio.channels
包含了文件系统和网络通讯相关的
channel
类。这个包通过
Selector
和
SelectableChannel
这两个类,还定义了一个进行非阻塞(
non-blocking
)
IO
操作的
API
,这对需要高性能
IO
的应用非常重要。
下面这张
UML
类图描述了
java.nio.channels
中
interface
的关系:
Channel
Channel
表现了一个可以进行
IO
操作的通道,该
interface
定义了以下方法:
boolean isOpen()
该
Channel
是否是打开的。
void close()
关闭这个
Channel
,相关的资源会被释放。
ReadableByteChannel
定义了一个可从中读取
byte
数据的
channel interface
。
int read(ByteBuffer dst)
从
channel
中读取
byte
数据并写到
ByteBuffer
中。返回读取的
byte
数。
WritableByteChannel
定义了一个可向其写
byte
数据的
channel interface
。
int write(ByteBuffer src)
从
ByteBuffer
中读取
byte
数据并写到
channel
中。返回写出的
byte
数。
ByteChannel
ByteChannel
并没有定义新的方法,
它的作用只是把
ReadableByteChannel
和
WritableByteChannel
合并在一起。
ScatteringByteChannel
继承了
ReadableByteChannel
并提供了同时往几个
ByteBuffer
中写数据的能力。
GatheringByteChannel
继承了
WritableByteChannel
并提供了同时从几个
ByteBuffer
中读数据的能力。
InterruptibleChannel
用来表现一个可以被异步关闭的
Channel
。这表现在两方面:
1.
当一个
InterruptibleChannel
的
close()
方法被调用时,其它
block
在这个
InterruptibleChannel
的
IO
操作上的线程会接收到一个
AsynchronousCloseException
。
2.
当一个
线程
block
在
InterruptibleChannel
的
IO
操作上时,另一个线程调用该线程的
interrupt()
方法会导致
channel
被关闭,该线程收到一个
ClosedByInterruptException
,同时线程的
interrupt
状态会被设置。
接下来的这张
UML
类图描述了
java.nio.channels
中类的关系:
非阻塞
IO
非阻塞
IO
的支持可以算是
NIO API
中最重要的功能,非阻塞
IO
允许应用程序同时监控多个
channel
以提高性能,这一功能是通过
Selector
,
SelectableChannel
和
SelectionKey
这
3
个类来实现的。
SelectableChannel
代表了可
以支持非阻塞
IO
操
作的
channel
,
可以将其注册在
Selector
上,这种注册的关系由
SelectionKey
这个类来表现(见
UML
图)。
Selector
这个类通过
select()
函数,给应用程序提供了一个可以同时监控多个
IO
channel
的方法:
应用程序通过调用
select()
函数,让
Selector
监控注册在其上的多个
SelectableChannel
,当有
channel
的
IO
操作可以进行时,
select()
方法就会返回以让应用程序检查
channel
的状态,并作相应的处理。
下面是
JDK 1.4
中非阻塞
IO
的一个例子,这段
code
使用了非阻塞
IO
实现了一个
time server
:
private
static
void
acceptConnections(
int
port)
throws
Exception
{
//
打开一个
Selector
Selector
acceptSelector
=
SelectorProvider.provider().openSelector();
//
创建一个
ServerSocketChannel
,这是一个
SelectableChannel
的子类
ServerSocketChannel
ssc
=
ServerSocketChannel.open();
//
将其设为
non-blocking
状态,这样才能进行非阻塞
IO
操作
ssc.configureBlocking(
false
);
margin: 0cm 0cm 0pt; text-align: le
分享到:
Global site tag (gtag.js) - Google Analytics
|
相关推荐
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
## **背景描述** 糖尿病是一种影响全球数百万人的慢性疾病,对公共健康构成重大威胁。准确预测糖尿病的发病风险对于早期干预和预防至关重要。通过机器学习模型分析影响糖尿病的主要因素,可以帮助医疗从业者更好地了解病因和风险因素,从而制定有效的预防和治疗策略。 本数据集来自Kaggle,包含了患者的各项健康指标及其是否患有糖尿病的标签。数据集的主要目标是通过机器学习模型预测糖尿病的发病风险,并分析影响糖尿病的主要健康因素。 ## **数据说明** | 字段名 | 说明 | | --- | --- | | PatientID | 患者ID | | Age | 年龄(岁) | | Gender | 性别,0:男,1:女 | | Ethnicity | 种族,0:白种人,1:非裔美国人,2:亚洲人,3:其他| | SocioeconomicStatus | 社会经济地位,0:低,1:中,2:高 | | EducationLevel | 教育水平,0:无,1:高中,2:学士学位,3:更高 | | BMI | 体质指数(体重(kg)/身高(m)^2) | | Smoking | 吸烟状况 |
端口扫面软件,自动检索出服务器开放的所有端口
该项目是一款基于Node.js和Vue.js构建的综合型项目源码,涉及207个文件,包括110个PNG图片、53个Vue组件、16个JavaScript文件、7个JSON配置、5个SCSS样式、4个JPG图片、2个文本文件、1个Git忽略规则文件、1个许可证文件和1个Markdown描述文件。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
梦幻西游道人是梦幻西游里面的一个NPC,主要是刷全服最实惠的高级兽决和其他很好用的比较贵的东西,在长安城、傲来国、长寿村中的任意一个场景出现,一般会出现30分钟,不过东西一般都被秒刷。 梦幻西游道人出现时间解析如下: 1.梦幻西游道人出现时间一直都保持着一年出现两次的规律,即2、3月份的元宵节期间来一次,9月份的教师节期间出现一次。 2.云游道人每个整点(0:00至7:00不出现)会在长安城、傲来国、长寿村中的任意一个场景出现,每次出现后停留时间为30分钟。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
2G+16G主程序物料号11173101 AML-962H机芯升级步骤 本地升级: 1、将2G+xG_update.zip重命名update.zip,拷贝至U盘,插入电视USB,打开电视进入设置 2、选择本地升级,升级完毕后电视会重启,操作过程中切勿断电关机 升级完成后可以在系统设置——本机信息——查询软件版本 强制升级: 1、解压强制升级脚本recovery.img与factory_update_param.aml,加上update.zip三个文件拷贝至U盘根目录,插入电视USB 2、插拔下电源,按遥控器待机键后快速不停点按遥控器右键5-10下触发主板识别U盘软件进行升级 3、升级完毕后电视会重启,操作过程中切勿断电关机 串口升级 1、将三个升级软件拷贝至U盘根目录下,然后插入电视的USB接口 2、电视开启的时候按住电脑键盘Enter回车键出现txl_p392_v1#时,输入run update敲回车,系统识别U盘软件进行升级 如未成功先确认输入指令是否正常,reboot重新启动再试 若还是无法升级可能是硬件存储系统的EMMC模块损坏,请更换主板
计算机图形学之动画和模拟算法:流体模拟中的物理约束.docx
jjjgbdfgdsfgsdggdfsdgf
一、项目简介 本项目是一套基于SSM框架扶贫信息综合平台前台管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse 确保可以运行! 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值 二、技术实现 spring+springmvc+mybatis+jsp+jquery+css 三、开发运行环境 jdk1.8 Tomcat8及其以上版本 Mysql5.5及以上版本 四、系统功能 系统分为两种用户:管理员,普通用户 前台功能: 首页 个人中心 用户登录 用户注册 政策信息:政策列表信息,浏览量 发布评论 推荐文章 最新评论文章 按关键字全局搜索文章 先进事例 下乡信息 后台功能: 用户管理 系统日志管理 文章管理 评论管理、文章分类 文章统计 人口管理 系统设置等功能 详见 https://blog.csdn.net/weixin_43860634/article/details/130546247
supermario!
计算机图形学之动画和模拟算法:流体模拟的优化与并行计算.docx
八上期中复习音频.zip
weixin049基于微信小程序校园外卖平台设计与实现+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
安卓 仿微信联系人,通讯录,右侧字母导航栏滑动联系人联动效果
实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip,含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,简单部署,就可以使用。该项目可以直接作为毕设、期末大作业使用,代码都在里面,系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值,项目都经过严格调试,确保可以运行! 实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实战项目-使用支持向量机(SVM)算法进行人脸识别源码.zip实
计算机图形学之动画和模拟算法:Cloth Simulation:离散动力学系统
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
2G+16G主程序物料号11173101 AML-962H机芯升级步骤 本地升级: 1、将2G+xG_update.zip重命名update.zip,拷贝至U盘,插入电视USB,打开电视进入设置 2、选择本地升级,升级完毕后电视会重启,操作过程中切勿断电关机 升级完成后可以在系统设置——本机信息——查询软件版本 强制升级: 1、解压强制升级脚本recovery.img与factory_update_param.aml,加上update.zip三个文件拷贝至U盘根目录,插入电视USB 2、插拔下电源,按遥控器待机键后快速不停点按遥控器右键5-10下触发主板识别U盘软件进行升级 3、升级完毕后电视会重启,操作过程中切勿断电关机 串口升级 1、将三个升级软件拷贝至U盘根目录下,然后插入电视的USB接口 2、电视开启的时候按住电脑键盘Enter回车键出现txl_p392_v1#时,输入run update敲回车,系统识别U盘软件进行升级 如未成功先确认输入指令是否正常,reboot重新启动再试 若还是无法升级可能是硬件存储系统的EMMC模块损坏,请更换主板