java new IO

Java中的IO和NIO(New IO)有什么区别? 在Java编程中,IO(Input/Output)和NIO(New IO)是两个重要的概念,它们分别代表了Java中的传统IO和新的IO库。为了全面解释这两者之间的区别,我们将从技术难点、面试官关注点、回答吸引力和代码举例四个方面进行详细描述。 阅读详情
原文地址:http://bbs.blueidea.com/thread-2679670-1-1.html,本文在此基础上做了一些修改。

PS:此文一般

Java New I/O的作用
当我们的JAVA程序会使用到大量的I/O操作,而程序性能很大一部分受到I/O影响的话,就可以考虑使用NIO来改写旧的I/O了~
所谓的NIO,就是JAVA类里的java.nio这个包~是J2SE1.4以后的版本才有的包~它提供了与传统I/O操作不同的解决方案,在I/O操作较多的时候,能在很大程度上提高程序性能。


基于旧的I/O的传统网络程序描述如下:
1)打开一个ServerSocket监听端口
2)程序在这里阻塞,直到有连接请求
3)读取请求、发送请求
4)关闭连接
5)重复2~4步


这就是传统的阻塞I/O操作,线程没有有效地利用cup,它们将大多数时间花费在I/O的阻塞上,所以这种线程是低效率的。


而非阻塞I/O以新的方式解决了阻塞问题,可以提高系统的效率。


NIO(new I/O)引入了四个概念:
·线性排列的数据缓冲,可读写缓冲
·一个字节码与Unicode字符的字符集映射
·双向通道Channels
·选择器Selectors




下面先来说说数据缓冲Buffer。
在一个Buffer中,position代表当前Buffer第一个能被读写的字节的位置,limit代表第一个不能被读写的字节的位置,capacity代表容量(这里读着有些拗口,是因为Buffer是双向的,如果读者一下子不能明白,可以看后面的解释)。对初始化的Buffer来说,position为0,limit=capacity。


在NIO中,通过Channel读写Buffer的数据。将一个Buffer中的数据写入Channel时必须调用Buffer对象的flip()方法(这里应该搞清楚,是Buffer与Channel交互的时候,才需要flip方法,如果是Buffer内部的自操作,是不需要的)。比如有以下代码:
ByteBuffer bb = ByteBuffer.allcateDirect(1024);
bb.put("this is a test".getBytes());
这两句的意思是:分配一个容量为1024的直接的ByteBuffer,通过put(byte[] b)方法将字符串存入到这个缓冲区bb里。而存在以下代码:
FileOutputStream out = new FileOutputStream("test.txt");
FileChannel channel = out.getChannel();
这时,当我们想把ByteBuffer对象里的数据写入到test.txt时,可以调用FileChannel的write(ByteBuffer)方法,但在这之前一定要先执行bb.flip(),然后再调用channel.write(bb);
flip()方法将缓冲区的position设为0,将limit设为现有数据的最后值。
如果不先调用flip(),则向test.txt里写入的东西就是空的~。


ByteBuffer是Buffer的子类,都位于java.nio包下面,该包下面还封装了其它基本数据类型的buffer,可以通过ByteBuffer的asCharBuffer()等方法得到其它基本类型的Buffer:


java.nio包如下:
ByteOrder                                 字节顺序的类型安全枚举。
Buffer                        一种用于特定的基本类型数据的容器。 
ByteBuffer                 字节缓冲区。  
CharBuffer                 字符缓冲区。 
DoubleBuffer                 double缓冲区。 
FloatBuffer                 float缓冲区。 
IntBuffer                 int缓冲区。 
LongBuffer                 long缓冲区。 
MappedByteBuffer         直接字节缓冲区,其内容是文件的内存映射区域。 
ShortBuffer                 short缓冲区。


二)字节码与Unicode字符的字符集映射


当需要将CharBuffer的存放的数据编码成ByteBuffer,再将ByteBuffer里存的数据解码成CharBuffer,这时候就要用到java.nio.charset.CharsetEncoder和java.nio.charset.CharsetDecoder了~~
(其实ByteBuffer有个asCharBuffer可以直接将ByteBuffer里的字节数据转换成字符数据的,但Charset类提供各种字符集比如utf-8、iso-8895-1等字符集的映射,可以将CharBuffer里的数据编码成各种格式的编码,然后再由CharsetDecoder解码)!下面是一个完整的程序代码,简单的展示了CharBuffer和ByteBuffer之间编码的转换:


package app.imo;


import java.nio.*;
import java.nio.charset.*;
public class CharsetTest {
        private ByteBuffer bb = null;
        private String s = "this is a test";
        public ByteBuffer encoder(){
                CharBuffer cb = CharBuffer.wrap(s);
                Charset cs = Charset.forName("UTF-8");
                CharsetEncoder ce = cs.newEncoder();
                try {
                        bb = ce.encode(cb); //将CharBuffer编码成ByteBuffer
                } catch (CharacterCodingException e) {
                        e.printStackTrace();
                }
                return bb;
        }
        public static void main(String[] args){
                CharsetTest ct = new CharsetTest();
                ByteBuffer bb = ct.encoder();
                Charset c = Charset.forName("UTF-8");
                CharsetDecoder cd = c.newDecoder();
                CharBuffer cb = null;
                try {
                        cb = cd.decode(bb);
                } catch (CharacterCodingException e) {
                        e.printStackTrace();
                }
                System.out.println(cb);
        }
}


三)NIO的核心技术:Selector、SelectableChannel和SelectionKey
说上面的三个类是NIO的核心技术我觉得一点都不为过~~
因为缓冲技术、字符集映射都是为它们准备的~~
三者位于java.nio.channels这个包里




Selector选择器,它将为我们监听所有的I/O操作,可以通过select()阻塞方法来确定什么时候在Channel中有数据流需要处理。可以由Selector类的静态方法Selector.open()获得一个Selector实例。Selector对象和SelectableChannel对象互为多路复用器。 
可以通过某个通道的register()方法注册到已经存在的选择器Selector。register()方法的声明如下:
public final SelectionKey register(Selector sel, int ops):向给定的选择器注册此通道,返回一个选择键。 
其中,sel - 要向其注册此通道的选择器,ops - 所得键的可用操作集。
ops可以有四个选择:
SelectionKey.OP_ACCEPT:               用于套接字接受操作的操作集位。
SelectionKey.OP_CONNECT:               用于套接字连接操作的操作集位。 
SelectionKey.OP_READ:                      用于读取操作的操作集位。
SelectionKey.OP_WRITE:                   用于写入操作的操作集位。


register()是SelectableChannel中定义的方法,SelectableChannel是一个抽象类,实现它的子类有DatagramChannel, Pipe.SinkChannel, Pipe.SourceChannel, ServerSocketChannel, SocketChannel。
要生成一个SelecableChannel实例,可以调用其子类的静态方法open(),比如说生成一个ServerSocketChannel实例,可以调用:
ServerSocketChannel ssc = ServerSocketChannel.open();
再通过调用ssc.socket().bind(InetSocketAddress)将ssc绑定到指定ServerSocket。
SelectableChannel的configureBlocking(boolean b)方法,设置为false时即将该通道配置为非阻塞的。
必须将通道配置成非阻塞的,才可以向Selector注册:
ssc.configureBlocking(false);
SelectionKey sk = ssc.register(selector,SelectionKey.OP_ACCEPT);
注册过以后,就可以调用selector.select()方法来选择一组相应的通道已为 I/O操作准备就绪的键了。


下面有二组代码,一组是基于NIO的,另一种是旧I/O的,大家可以对比参考下:
旧I/O客户端:
Socket s = new Socket("localhost",1111);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str;
while((str=in.readLine())!=null){
        System.out.println(str);
}
旧I/O服务端:
ServerSocket ss = new ServerSocket(1111);
Socket c = ss.accept();//这里阻塞,标志着每一个ServerSocket都需要阻塞
PrintWriter out = new PrintWriter(c.getOutputStream(),true);
out.write("hello,client".getBytes());




NIO客户端:
SocketChannel channel = SocketChannel.open();
channel.connect(new InetSocketAddress("localhost",1111));
ByteBuffer buffer = ByteBuffer.allocateDirect(512);
channel.read(buffer);


NIO服务端:
Selector selector = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(1111));
ssc.configureBlocking(false);
ssc.register(selector,SelectionKey.OP_ACCEPT);
ssc.select();//这里阻塞,标志着所有ServerSocketChannel可以共用一个阻塞。
java.util.Set keys = ssc.selectedKeys();
java.util.Iterator i = keys.iterator();
while(i.hasNext()){
  SelectionKey key = i.next;
  i.remove();


  ServerSocketChannel serverSocket = (ServerSocketChannel)key.channel();
  SocketChannel socket = serverSocket.accept();
  ByteBuffer buf = ByteBuffer.wrap("hello,client\n".getBytes());
  socket.write(buf);
}




http://blog.sina.com.cn/s/blog_4c925dca0100hmvg.html
http://www.goldendoc.org/category/java-nio/

从宁德新能源面试官视角,拆解Halcon/OpenCV图像处理工程师的硬核技能树(附避坑指南) 本文从宁德新能源面试官视角出发,详细拆解Halcon/OpenCV图像处理工程师的核心技能树,涵盖硬件选型、算法实现和系统工程思维三大能力维度。文章提供工业视觉工程师面试的实战避坑指南,包括硬件配置要点、算法优化技巧及职业发展路径,助力求职者系统提升图像处理专业技能。 阅读详情

相关推荐

空频、空时、空域、时域、频域抗干扰介绍

1、时域抗干扰:对时间域序列进行滤波,滤波系数h(n),采样序列不断进行输入与滤波系数卷积计算,得到响应输出;例如常用的FIR和IIR滤波器。 对于多窄带干扰噪声源和连续波干扰源有较好的处理效果,还可以解决多径问题; 可以通过在接收机前端处理中增加一个嵌入式块实现; 2、频域抗干扰:接收机不容易受到相对于接收机频带以外的强功率干扰; 通常为带通滤波和阻带滤波, 适用于窄带干扰噪声源,连续波干扰源以及较强的频带外干扰噪声源, 3、空域抗干扰:通过多个自适应天线按照特定组合成天线阵列,波束成形,针对

qq_43517907的博客 7301

JAVA NIO(New IO)

一.了解NIO 1.什么是NIO 首先我们要明白传统IO比如InputStream,OutputStream,在执行read()和write()时是会阻塞的,直到数据准备好才会被唤醒。 NIO,是一种非阻塞IO,NIO 从JDK1.4提出的,本意是New l0,它的出现为了弥补传统I0的不足,提供了更高效的方式 NIO在处理网络数据时底层用到(select/poll)模型 多路复用 (可以提升服务端处理连接的数量)jdk1.5使用了epoll代替了select/poll 2.NIO的新特性 .

w7486的博客 871

【模型解读】【代码复现】Segment Anything Model(SAM)

Meta AI的一个新的人工智能模型,只需一次点击就能 "分割出 "任何图像中的任何物体! SAM是一个可提示的分割系统,对不熟悉的物体和图像具有zero-shot的概括性,并且不需要额外的训练。

lalula的博客 2万+

New IO

NIO、NewIO

qq_32076957的博客 682

用Multisim仿真石英晶体振荡电路:从等效模型到频响曲线实战

本文通过Multisim软件,从构建石英晶体等效电路模型入手,详细演示了如何仿真分析其电抗频率特性曲线,并实战搭建与调试皮尔斯振荡电路。文章深入探讨了振荡必须工作在串联与并联谐振点之间感性区的原因,为电子设计者提供了从理论到仿真的完整可视化学习路径。

ik67890123的博客 500

快速上手springboot+vue的前后端分离项目

使用webStorm新建项目后,把 .lock文件删除后项目运行才不报错,配置文件 vue.config.js 中加入 lintOnSave: false 关闭eslint语法检测。在多层嵌套的父子组件之间传递状态已经十分麻烦,而Vue更是没有为兄弟组件提供直接共享数据的办法。基于这个问题,许多框架提供了解决方案——使用全局的状态管理器,将所有分散的共享数据交由状态管理器保管,Vue也不例外。其中一种解决CORS 的方法, 在springboot项目中跨域的方法或类加上@CrossOrigin注解。

m0_61950264的博客 1904

NIO&Netty编程

什么是NIO? Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 NIO的几个核心元素 Java NIO: Channels and Buffers(通道和缓冲区): 标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数...

qq_42292373的博客 493

【ubuntu】【VirtualBox】VirtualBox无法加载USB移动设备的解决方法(支持U盘启动盘)

提示:测试可用。

联系方式:927632640 2439

java new io_Java New IO

1、NIO介绍应用程序中,通常会涉及两种类型的计算:计算密集型和I/O密集型。对多数应用来说,花费在等待IO上的时间是比较大的。因此提高IO操作效率对应用的性能至关重要。面向流的IO系统一次处理一个字节的数据,效率低。New I/O提供高速、面向块的I/O处理机制,每个操作都产生或消费一个数据块, 按块处理数据比按字节处理数据快得多,只不过处理上少了一点优雅性。NIO库在java.nio包中,ja...

weixin_29103027的博客 220

【WorkBuddy专栏19】技能的创造与迁移——从零开始打造你的AI工作流

【WorkBuddy专栏19】技能的创造与迁移——从零开始打造你的AI工作流

AI人人懂 369

知识图谱-KGE-语义匹配-双线性模型-2018:SimplE

【paper】 SimplE Embedding for Link Prediction in Knowledge Graphs 【简介】 本文是加拿大英属哥伦比亚大学的两位学者发表在 NIPS 2018 上的工作,文章提出了 SimplE(Simple Embedding)。这篇和前面一篇差不多,也是对 1927 年的 CP 进行改进(简化),传统CP为实体分配的两个向量是独立训练的,SimplE利用关系的逆在三元组打分函数中加上了一个对称项,使得每个实体的两个向量依赖学习,并且 SimplE 的复杂度随

u013250861的博客 958

Java NIO(New IO) 通俗易懂简明教程

Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。本系列教程将有助于你学习和理解Java NIO。

程序员备忘录 7593

Python 爬虫高级实战:HTTPS 证书忽略与代理抓包配置

本文深入解析了HTTPS加密与SSL证书校验机制在爬虫开发中的核心问题及解决方案。文章首先剖析了HTTPS协议架构和证书校验流程,指出爬虫开发中常见的证书异常场景及其负面影响。随后详细介绍了Python主流请求库(requests、httpx、aiohttp)的证书忽略配置方法,包括同步/异步模式下的实现方案。针对代理环境,文章系统比较了HTTP、HTTPS、SOCKS5等代理类型的特性差异,并提供了完整的代理配置示例。特别对中间人抓包场景,阐述了Mitmproxy的工作原理和配置要点。最后提出了工程级爬虫

2503_91057718的博客 85

Java New IO 和 异步 IO,哪一个用的比较多?

尤其是在传统的高并发网络应用中。而AIO则在需要更高性能和异步处理能力的场景中逐渐得到更多关注。选择哪种IO模型,通常取决于具体的应用需求和性能要求。Java New IO(NIO)和异步 IO(AIO)在不同的场景下各有其应用。NIO由于其相对简单和成熟,在Java应用中使用得比较广泛。

Frank 的博客 477

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

JAVA基础十五 java new io

java new io是相对于传统io来说的,传统的io模型是指 通过 inputstream和outputstream 输入和输出 都是读写都是阻塞的, java new io 采用 channel buffer selector 数据是通过 channel传递,是双向的,可读可写。将buffer中的数据写入通道或者从通道读数据到buffer。 new io实现非阻塞io其实本质上还是阻塞的,只不过通过io多路复用技术实现非阻塞操作。多路复用是指可以通过一个selector监听通道事件,通过事先注册事件.

JAVA_HOME_NEW的博客 345

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

用Java的New IO开发网络协议

最近用Java的New IO开发了一套简单的网络协议,在这里我把开发中的一些心得整理一下,总结出一套简单的可以重用的网络协议开发框架,希望能够给初学者一点帮助。网络协议基本的通讯单位是一个一个的消息包。在用socket传输这些包的时,首先要解决的一个问题是如何解决包与包之间的边界问题。socket传输的是流,一个send中发出的消息,在对方不一定在一个recv中收到,可能要多次recv,或者一个r

jinhuaxing的专栏 1756

JAVA NIO(new IO)

1.简介 Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。 1.1.IO和NIO的区别: IO和NIO的区别 IO NIO 面向流(Stream Oriented) 面向缓冲区(Buffer Oriented) 阻塞IO(Blocking ...

Mr_Liuxz的博客 798

java nio改造io,java nio (new IO)

IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。所有语言运行时系统提供执行 I/O 较高级别的工具。 (c 的 printf scanf,java 的面向对象封装 )2.Java标准 io回顾Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底层实现,我们无须关注底层实现。 InputStre...

weixin_42373997的博客 193

java new io_Java IO简介

一、java io 概述1.1 相关概念Java IOJava IO即Java 输入输出系统。不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO(文件、控制台、网络),我们还要考虑具体和它们的通信方式(顺序、随机、二进制、按字符、按字、按行等等)。Java类库的设计者通过设计大量的类来攻克这些难题...

weixin_39980129的博客 204

Java NIO是New IO还是Non-blocking IO

很多小伙伴对Java NIO的一些概念和编程不是很理解,希望通过本文对Java NIO与传统IO的对比,可以帮助大家更好地理解和掌握Java NIO。Java NIO 并不是完全非阻塞,只是通过事件驱动机制和缓冲区减少系统调用次数,减少了阻塞等待的时间。理解Java NIO需要重点理解事件驱动机制。

二蛋的博客 1669

【Java】New IO

1.   基本 概念 IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。 所有语言运行时系统提供执行 I/O 较高级别的工具。 (c 的 printf scanf,java 的面向对象封装 ) 2.    Java 标准 io 回顾 Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底层

sdu_yujielei的专栏 709

java IO ——new I/O包

新IO系统基于两个最简单的项目:通道和缓存区。通道代表对一个IO源或目标的开放式连接,缓存区存放可操作的数据,NIO是异步非阻塞式调用io系统 同步、异步、阻塞、非阻塞 同步是一个连接一个线程,而异步是一个请求一个线程,阻塞是当读取不到数据时线程会等待,非阻塞是线程发出数据请求后转而向下执行,当数据加载好时通知线程 NIO基础 fileinputstream f = new

一叶吴舟 398

Java New IO

1.   基本 概念 IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。 所有语言运行时系统提供执行 I/O 较高级别的工具。 (c 的 printf scanf,java 的面向对象封装 ) 2.    Java 标准 io 回顾 Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底...

斗牛士 149

Java IO 为什么要写成 `new A(new B(new C()))` 这么丑?

装饰器模式的灵魂在于“包装”。动态: 你不需要在编译时决定对象的功能,可以在运行时随意组合。灵活: 想加功能?写个新装饰器套上去就行,不用改原来的代码(符合开闭原则)。

郑龙飞 717

《JAVA》New IO 简单介绍(Channel,Buffer)

Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java1.4开始),Java NIO提供了与标准IO不同的IO工作方式。Channels and Buffers(通道和缓冲区)标准的俄IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入通道也类似。Non-b...

CallmeZhe的博客 436

用Java的New IO开发网络协议(转)

最近用Java的New IO开发了一套简单的网络协议,在这里我把开发中的一些心得整理一下,总结出一套简单的可以重用的网络协议开发框架,希望能够给初学者一点帮助。网络协议基本的通讯单位是一个一个的消息包。在用socket传输这些包的时,首先要解决的一个问题是如何解决包与包之间的边界问题。socket传输的是流,一个send中发出的消息,在对方不一定在一个recv中收到,可能要多次recv,或者一

hzzwh的专栏 714
上一篇: Iphone开发(6) 如何保证不出现内存泄露
下一篇: 全面解析NIO
coding_or_coded
博客等级 码龄16年 216粉丝 115原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值