java nio(non-blocking io)简介及和io
在 Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节 的数据,面向流的I/O速度非常慢,而在Java 1.4中推出了NIO,这是一个面向块的I/O系统,系统以块的方式处理处理,每一个操作在一步中产生或者消费一个数据库,按块处理要比按字节处理数据快 的多。
在NIO中有几个核心对象需要掌握:缓冲区(Buffer)、通道(Channel)、选择器(Selector)。
缓冲区Buffer
缓冲区实际上是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的; 在写入数据时,它也是写入到缓冲区中的;任何时候访问 NIO 中的数据,都是将它放到缓冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到Stream对象中。
在NIO中,所有的缓冲区类型都继承于抽象类Buffer,最常用的就是ByteBuffer,对于Java中的基本类型,基本都有一个具体Buffer类型与之相对应,它们之间的继承关系如下图所示:

下面是一个简单的使用IntBuffer的例子:
- import java.nio.IntBuffer;
- public class TestIntBuffer {
- public static void main(String[] args) {
- // 分配新的int缓冲区,参数为缓冲区容量
- // 新缓冲区的当前位置将为零,其界限(限制位置)将为其容量。它将具有一个底层实现数组,其数组偏移量将为零。
- IntBuffer buffer = IntBuffer.allocate(8);
- for (int i = 0; i < buffer.capacity(); ++i) {
- int j = 2 * (i + 1);
- // 将给定整数写入此缓冲区的当前位置,当前位置递增
- buffer.put(j);
- }
- // 重设此缓冲区,将限制设置为当前位置,然后将当前位置设置为0
- buffer.flip();
- // 查看在当前位置和限制位置之间是否有元素
- while (buffer.hasRemaining()) {
- // 读取此缓冲区当前位置的整数,然后当前位置递增
- int j = buffer.get();
- System.out.print(j + " ");
- }
- }
- }
运行后可以看到:

在后面我们还会继续分析Buffer对象,以及它的几个重要的属性。
通道Channel
通道是一个对象,通过它可以读取和写入数据,当然了所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道中,相反是将数据写入包含一个或者多个字节的缓冲区。同样不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
在NIO中,提供了多种通道对象,而所有的通道对象都实现了Channel接口。它们之间的继承关系如下图所示:

使用NIO读取数据
在前面我们说过,任何时候读取数据,都不是直接从通道读取,而是从通道读取到缓冲区。所以使用NIO读取数据可以分为下面三个步骤:
1. 从FileInputStream获取Channel
2. 创建Buffer
3. 将数据从Channel读取到Buffer中
下面是一个简单的使用NIO从文件中读取数据的例子:
- import java.io.*;
- import java.nio.*;
- import java.nio.channels.*;
- public class Program {
- static public void main( String args[] ) throws Exception {
- FileInputStream fin = new FileInputStream("c:\\test.txt");
- // 获取通道
- FileChannel fc = fin.getChannel();
- // 创建缓冲区
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- // 读取数据到缓冲区
- fc.read(buffer);
- buffer.flip();
- while (buffer.remaining()>0) {
- byte b = buffer.get();
- System.out.print(((char)b));
- }
- fin.close();
- }
- }
使用NIO写入数据
使用NIO写入数据与读取数据的过程类似,同样数据不是直接写入通道,而是写入缓冲区,可以分为下面三个步骤:
1. 从FileInputStream获取Channel
2. 创建Buffer
3. 将数据从Channel写入到Buffer中
下面是一个简单的使用NIO向文件中写入数据的例子:
- import java.io.*;
- import java.nio.*;
- import java.nio.channels.*;
- public class Program {
- static private final byte message[] = { 83, 111, 109, 101, 32,
- 98, 121, 116, 101, 115, 46 };
- static public void main( String args[] ) throws Exception {
- FileOutputStream fout = new FileOutputStream( "c:\\test.txt" );
- FileChannel fc = fout.getChannel();
- ByteBuffer buffer = ByteBuffer.allocate( 1024 );
- for (int i=0; i<message.length; ++i) {
- buffer.put( message[i] );
- }
- buffer.flip();
- fc.write( buffer );
- fout.close();
- }
- }
本文介绍了Java NIO中三个核心概念中的两个,并且看了两个简单的示例,分别是使用NIO进行数据的读取和写入,Java NIO中最重要的一块Nonblocking I/O将在第三篇中进行分析,下篇将会介绍Buffer内部实现。
个别参数解释:
position:指定了下一个将要被写入或者读取的元素索引,它的值由get()/put()方法自动更新,在新0
创建一个Buffer对象时,position被初始化为0。
limit:指定还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时)。
capacity:指定了可以存储在缓冲区中的最大数据容量,实际上,它指定了底层数组的大小,或者至少是指定了准许我们使用的底层数组的容量。
以上四个属性值之间有一些相对大小的关系:0 <= position <= limit <= capacity。如果我们创建一个新的容量大小为10的ByteBuffer对象,在初始化的时候,position设置为0,limit和 capacity被设置为10,在以后使用ByteBuffer对象过程中,capacity的值不会再发生变化,而其它两个个将会随着使用而变化。
-------------------------------Channel与io 区别----------------------------------
java nio(non-blocking io)简介及和io的更多相关文章
- 【Java nio】Blocking nio2
package com.slp.nio; import org.junit.Test; import java.io.File; import java.io.IOException; import ...
- 【Java nio】 Blocking nio
package com.slp.nio; import org.junit.Test; import java.io.File; import java.io.IOException; import ...
- 《JAVA NIO》第一章 简介
1.2 CPU已不再是束缚 相反,是JVM 自身在I/O 方面效率欠佳.操作系统与Java 基于流的I/O模型有些不匹配. 操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取(DMA) ...
- Java NIO学习系列四:NIO和IO对比
前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...
- JAVA NIO是什么(zz)
JAVA NIO是什么? 1. 基本 概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系 ...
- Java NIO API详解
在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的同步(blocking)API.对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端 ...
- Java NIO 概览
Java面试通关手册(Java学习指南) Github地址:https://github.com/Snailclimb/Java_Guide 一 NIO简介 Java NIO 是 java 1.4 之 ...
- Netty 源码分析之 番外篇 Java NIO 的前生今世
简介 Java NIO 是由 Java 1.4 引进的异步 IO. Java NIO 由以下几个核心部分组成: Channel Buffer Selector NIO 和 IO 的对比 IO 和 NI ...
- [翻译] java NIO 教程---介绍
原文地址:http://tutorials.jenkov.com/java-nio/index.html Java NIO(new IO)是从java1.4之后的对IO API的另一种选择,即对标准j ...
随机推荐
- 用python爬取QQ空间
好久没写博文了,最近捣鼓了一下python,好像有点上瘾了,感觉python比js厉害好多,但是接触不久,只看了<[大家网]Python基础教程(第2版)[www.TopSage.com]> ...
- python调用zabbix接口实现Action配置
要写这篇博客其实我的内心是纠结的,老实说,我对zabbix的了解实在不多.但新公司的需求不容置疑,当我顶着有两个头大的脑袋懵懵转入运维领域时,面前摆着两百多组.上千台机器等着写入zabbix监控的需求 ...
- 3个sprint的团队贡献分
第一次冲刺贡献分 成员名字 贡献分 101丘娟 23 108周诗琦 26 107杨晓霞 24 124陈程 27 第二次冲刺贡献分 成员名字 贡献分 101丘娟 23 108周诗琦 27 ...
- sprint one
产品backlog Id Name Imp Est How to demo 1 各个角色账号登录功能 30 20 建立数据库,数据库中存储一些角色的初始账号以便测试,输入账号密码,系统在数据库中查找账 ...
- Python’s SQLAlchemy vs Other ORMs[转发 6]SQLAlchemy
SQLAlchemy SQLAlchemy is an open source SQL toolkit and ORM for the Python programming language rele ...
- 虚拟化--IO虚拟化基本原理
本文话题: IO虚拟化概述 设备发现 访问截获 设备模拟 设备共享基于软件的IO虚拟化 基于前端后端的IO虚拟化基于硬件的IO虚拟化 概述 从处理器的角度看,外设是通过一组I/O资源(端口I/O或者是 ...
- SQL SERVER 2005 DBCC PAGE命令说明
夏日福利: 小泽玛利亚的“专业摄影”性感写真集:http://947kan.com/video/player-52475-0-0.html ------------------------------ ...
- Redis一个异常的解决办法,异常描述:Could not get a resource from the pool
异常描述: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poo ...
- MySql学习(四) —— 函数、视图
注:该MySql系列博客仅为个人学习笔记. 本篇博客主要涉及MySql 函数(数学函数.字符串函数.日期时间函数.流程控制函数等),视图. 一.函数 1. 数学函数 对于数学函数,若发生错误,所有数学 ...
- jquery触屏幻灯片
一.前言 去年接触了移动Web开发,做了些手机端的网站及应用,还有些小的微信游戏和活动页面.每个项目里或多或少的都会有一些触屏事件等.其中有两个用到了jquery触屏幻灯片.刚开始的时候也在百度上搜索 ...