- 浏览: 2184709 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
从JDK1.4开始,Java 提供了一系列改进的输入和输出处理的新功能,这些功能被称为新IO,新增了许多用于处理输入,输出的类,这些类都被放在java.nio的包以及子包下,并且对原java.io包中的很多类都以NIO的方式,进行了改写,新增了满足NIO的功能。
新IO和传统的IO有相同的目的,都是用于进行输入和输出的,但新IO使用了不同的方式来处理输入输出,新IO采取的方式是采用内存映射的方式来处理输入输出,新IO将文件或文件中的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了,这种方式类似虚拟内存的概念,通过这种方式来进行输入输出比传统的输入输出要快的多。
Channel(通道)和Buffer(缓冲)是新IO中的两个核心对象,Channel是对传统的输入输出系统的模拟,在新IO系统中所有的数据都要通过通道传输,他们之间的最大区别就是它提供了一个map方法,可以通过该map方法将一块数据映射到内存中,传统的IO是面向流的处理,而新的IO则是面向块的处理。
Buff可以被理解成一个容器,它的本质是一个数组,发送到Channel的所有对象都必须放在Buffer中,而从Channel中,读取的数据也必须先放到Buffer中,除了Channel和Buffer之外,新IO还提供了用于将Unicode字符串映射成字节序列以及逆映射的操作的Charset类,也提供了支持支持非阻塞式的Selector类。
Buffer类的几个方法如下:
注意,使用put或get访问Buffer中的数据时,分为绝对和相对来种情况:
相对:从Buffer的当前position处开始读取或写入数据,然后将位置的值按处理元素的个数增加
绝对: 直接根据索引向Buffer中读取或写入数据,使用绝对方式访问Buffer里的数据时,并不会影响位置的值。
下面散仙给出测试的例子:
输出结果如下:
Channel与Buffer的简单测试:
新IO和传统的IO有相同的目的,都是用于进行输入和输出的,但新IO使用了不同的方式来处理输入输出,新IO采取的方式是采用内存映射的方式来处理输入输出,新IO将文件或文件中的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了,这种方式类似虚拟内存的概念,通过这种方式来进行输入输出比传统的输入输出要快的多。
Channel(通道)和Buffer(缓冲)是新IO中的两个核心对象,Channel是对传统的输入输出系统的模拟,在新IO系统中所有的数据都要通过通道传输,他们之间的最大区别就是它提供了一个map方法,可以通过该map方法将一块数据映射到内存中,传统的IO是面向流的处理,而新的IO则是面向块的处理。
Buff可以被理解成一个容器,它的本质是一个数组,发送到Channel的所有对象都必须放在Buffer中,而从Channel中,读取的数据也必须先放到Buffer中,除了Channel和Buffer之外,新IO还提供了用于将Unicode字符串映射成字节序列以及逆映射的操作的Charset类,也提供了支持支持非阻塞式的Selector类。
Buffer类的几个方法如下:
方法名 | 描述 |
capacity() | 返回的buffer的容量大小 |
hasRemaining() | 当前位置position和limit之间是否还有元素可供处理 |
limit() | 返回界限值 |
mark() | 在0和position之间做位置标记 |
position() | buffer中的position值 |
remaining() | 返回当前位置和界限之间的元素个数 |
reset() | 将位置转到mark所在的位置 |
rewind() | 将位置设置0,取消mark标记 |
put() | 支持批量的数据写入 |
get() | 支持数据读取 |
注意,使用put或get访问Buffer中的数据时,分为绝对和相对来种情况:
相对:从Buffer的当前position处开始读取或写入数据,然后将位置的值按处理元素的个数增加
绝对: 直接根据索引向Buffer中读取或写入数据,使用绝对方式访问Buffer里的数据时,并不会影响位置的值。
下面散仙给出测试的例子:
package com.qin.sanxian.newio; import java.nio.CharBuffer; /** * @author 三劫散仙 * 测试Java 新IO的buffer * * */ public class TestBuffer { public static void main(String[] args)throws Exception { //创建一个Buffer对象,allcote分配的容量为8 CharBuffer buff=CharBuffer.allocate(8); System.out.println("容量:"+buff.capacity()); System.out.println("限制大小,limit: "+buff.limit()); System.out.println("位置: position: "+buff.position()); //放入三个元素 buff.put("a"); buff.put("b"); buff.put("c"); System.out.println("加入三个元素后位置 : "+buff.position()); //此方法是会将limit设置为position的位置,将position的位置为0 buff.flip(); System.out.println("执行filp后,limit的位置:"+buff.limit()); System.out.println("执行filp后,position的位置:"+buff.position()); //取出,第一个元素后 System.out.println(buff.get(0)); System.out.println("position: "+buff.position()); //调用clear方法后 ,将position置为0,limit置为capacity buff.clear(); System.out.println("执行clean后,limit ="+buff.limit()); System.out.println("执行clean后,position = "+buff.position()); System.out.println("执行clear后,缓冲区的内容没有被清除: "+buff.get(0)); System.out.println("执行绝对读取后,position= "+buff.position()); } }
输出结果如下:
容量:8 限制大小,limit: 8 位置: position: 0 加入三个元素后位置 : 3 执行filp后,limit的位置:3 执行filp后,position的位置:0 a position: 0 执行clean后,limit =8 执行clean后,position = 0 执行clear后,缓冲区的内容没有被清除: a 执行绝对读取后,position= 0
Channel与Buffer的简单测试:
package com.qin.sanxian.newio; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; /** * * Channel测试 * **/ public class TestChannel { public static void main(String[] args) throws Exception{ //read(); // write(); moreRead(); } /** * * 读取一个文件的数据 * 写入到另一个文件里 * **/ public static void read()throws Exception{ File f=new File("F:\\1\\text.txt"); //创建流获取channel对象 FileChannel inChannel=new FileInputStream(f).getChannel(); FileChannel outChannel=new FileOutputStream("abc.txt").getChannel(); //将FileChannel里的数据全部映射成ByteBuffer; MappedByteBuffer buffer=inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length()); //将f的数据全部输出 outChannel.write(buffer); buffer.clear();//复原位置 Charset c=Charset.forName("UTF-8"); CharsetDecoder decoder=c.newDecoder();//创建解码器 //解码buffer CharBuffer charBuffer=decoder.decode(buffer); System.out.println(charBuffer); outChannel.close();//关闭流 inChannel.close();//关闭流 } /** * * 写入测试 * */ public static void write()throws Exception{ File f=new File("F:\\1\\text.txt"); //获取一个RandomAccessFile对象 RandomAccessFile raf=new RandomAccessFile(f, "rw"); //获取FileChannel FileChannel channel=raf.getChannel(); //将文件全部映射到内存中 ByteBuffer buffer=channel.map(FileChannel.MapMode.READ_WRITE, 0, f.length()); //控制原来的的指针到最后一步 channel.position(f.length()); channel.write(buffer);//拷贝已有数据 channel.close();//释放资源 raf.close();//关闭流 } /** * 多次读取数据 * * **/ public static void moreRead()throws Exception{ FileInputStream f=new FileInputStream(new File("F:\\1\\text.txt")); //创建一个fileChannel FileChannel channel=f.getChannel(); //定义一个ByteBuffer对象 ByteBuffer buff=ByteBuffer.allocate(103); //将FileChannel的数据放入ByteBuffer中 while(channel.read(buff)!=-1){ buff.flip();//封印未读取的空间 //创建Charset对象 Charset charset=Charset.forName("UTF-8"); //创建解码器对象 CharsetDecoder decoder=charset.newDecoder(); //将字节内容转码 CharBuffer cbuff=decoder.decode(buff); System.out.println(cbuff); //为下一次,读取数据做准备,注意其并不会清空缓存内容 buff.clear(); } channel.close(); f.close(); } }
发表评论
-
记一次log4j不打印日志的踩坑记
2019-09-22 01:58 1572### 起因 前几天一个跑有java应用的生产集群(200多 ... -
在Java里面如何解决进退两难的jar包冲突问题?
2019-07-23 19:10 1234如上图所示: es api组件依赖guava18.0 ... -
如何轻松理解二叉树的深度遍历策略
2019-07-03 23:33 1129我们知道普通的线性数据结构如链表,数组等,遍历方式单一 ... -
为什么单线程Redis性能也很出色
2019-01-21 18:02 2208高性能的服务器,不一 ... -
如何将编程语言里面的字符串转成数字?
2019-01-11 23:23 2094将字符串转成数字在很 ... -
为什么Java里面String类是不可变的
2019-01-06 18:36 1669在Java里面String类型是不可变对象,这一点毫无疑问,那 ... -
关于Java里面volatile关键字的重排序
2019-01-04 18:49 1068Java里面volatile关键字主 ... -
多个线程如何轮流打印ABC特定的次数?
2018-12-11 20:42 6043之前的一篇文章,我给 ... -
聊聊Java里面的引用传递
2018-11-16 21:21 990长久以来,在Java语言里面一直有一个争论,就是Java语言到 ... -
理解计数排序算法的原理和实现
2018-10-11 10:03 2092计数排序(Counting sort) ... -
理解Java7和8里面HashMap+ConcurrentHashMap的扩容策略
2018-09-06 11:31 3389### 前言 理解HashMap和Con ... -
关于Java里面多线程同步的一些知识
2018-07-18 09:45 1108# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
Java单例模式之双检锁深入思考
2018-07-08 12:25 3290# Java单例模式之双检锁 ... -
关于Java里面多线程同步的一些知识
2018-07-08 12:23 1122# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
重新认识同步与异步,阻塞和非阻塞的概念
2018-07-06 14:30 1474# 重新认识同步与异步 ... -
线程的基本知识总结
2018-06-27 16:27 1062### (一)创建线程的方式 (1)实现Runnable接口 ... -
Java里面volatile关键字修饰引用变量的陷阱
2018-06-25 11:42 1387# Java里面volatile关键字修饰引用变量的陷阱 如 ... -
关于Java里面的字符串拼接,你了解多少?
2018-06-25 11:28 1371# 关于Java里面的字符串 ... -
深入理解Java内存模型的语义
2018-06-25 11:39 740### 前言 Java内存模型( ... -
如何证明Java多线程中的成员变量数据是互不可见的
2018-06-21 10:09 1502前面的几篇文章主要介绍了Java的内存模型,进程和线程的定义, ...
相关推荐
Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) SocketChannel Java NIO系列教程(九) ServerSocketChannel Java NIO...
java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...
Java NIO,全称为Non-...总的来说,Java NIO提供了比传统I/O更灵活、更高效的数据传输机制,尤其适用于需要处理大量并发连接的网络应用,如服务器端的开发。通过合理利用NIO的特性,可以构建出高性能、低延迟的系统。
总的来说,Java NIO是一个强大的工具,对于需要处理大量并发连接和数据交换的应用来说,它提供了显著的性能提升。Netty则是NIO的一个高级封装,它进一步降低了使用NIO的复杂性,提高了开发效率。学习和理解Java NIO...
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...
### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...
Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...
总的来说,Java NIO提供了一种高效、灵活的I/O模型,尤其适合处理高并发的网络应用。这个例子"一个java NIO的例子"是学习和理解Java NIO概念和机制的一个很好的起点。通过分析和运行这个示例,开发者可以更深入地...
java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...
Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...
java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...
总的来说,Java NIO提供了一种更高效、灵活的方式来处理文件读取和其他I/O操作,尤其适合需要处理大量并发I/O请求的场合,例如服务器端编程。通过熟练掌握NIO,开发者可以构建出更加高效的Java应用程序。