`
qindongliang1922
  • 浏览: 2180954 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117400
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:125817
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59788
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71225
社区版块
存档分类
最新评论

来点实用的Java NIO(五)

    博客分类:
  • JAVA
阅读更多
从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类的几个方法如下:

方法名描述
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();
		
	}
	
}




分享到:
评论
2 楼 qindongliang1922 2013-12-10  
ahern88 写道
仙哥总结的很好~

呵呵,你小子又来了 ,加油!
1 楼 ahern88 2013-12-10  
仙哥总结的很好~

相关推荐

    JavaNIO chm帮助文档

    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 NIO和java并发编程的书籍java...

    java NIO.zip

    Java NIO,全称为Non-...总的来说,Java NIO提供了比传统I/O更灵活、更高效的数据传输机制,尤其适用于需要处理大量并发连接的网络应用,如服务器端的开发。通过合理利用NIO的特性,可以构建出高性能、低延迟的系统。

    Java NIO英文高清原版

    总的来说,Java NIO是一个强大的工具,对于需要处理大量并发连接和数据交换的应用来说,它提供了显著的性能提升。Netty则是NIO的一个高级封装,它进一步降低了使用NIO的复杂性,提高了开发效率。学习和理解Java NIO...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO 视频教程

    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简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    一个java NIO的例子

    总的来说,Java NIO提供了一种高效、灵活的I/O模型,尤其适合处理高并发的网络应用。这个例子"一个java NIO的例子"是学习和理解Java NIO概念和机制的一个很好的起点。通过分析和运行这个示例,开发者可以更深入地...

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    Java NIO测试示例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...

    Java NIO Socket基本

    Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...

    java基于NIO实现Reactor模型源码.zip

    java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...

    java nio 读文件

    总的来说,Java NIO提供了一种更高效、灵活的方式来处理文件读取和其他I/O操作,尤其适合需要处理大量并发I/O请求的场合,例如服务器端编程。通过熟练掌握NIO,开发者可以构建出更加高效的Java应用程序。

Global site tag (gtag.js) - Google Analytics