JAVA NIO中的Channels和Buffers
前言
Channels和Buffers是JAVA NIO里面比较重要的两个概念,NIO正是基于Channels和Buffers进行数据操作,且数据总是从Channels读取到Buffers,或者从Buffers写入到Channels。
通道(Channel)
NIO中的通道与IO中的流类似,不过流是单向的,而通道是双向的。例如InputStream、OutputStream等都是单向的,一个流只能进行读数据或写数据;而FileChannel、SocketChannel等是双向的,既可以从中读数据,也可以写数据。
通道与流的区别如下:
- 通道是双向的,可读可写,而流是单向的,只能读或只能写;
- 通道中的数据是跟Buffer进行交互的,但在面向流的I/O中,数据是直接读/写到流中的;
- NIO可以异步读写数据;
以FileChannel为例,如下:
FileChannel
FileChannel是文件写入/读取相关的通道;
产生FileChannel的方式:
- 从FileOutputStream中获取;
- 从RandomAccessFile中获取;
- 从FileInputStream中获取;
下面举个例子,分别从FileOutputStream、RandomAccessFile、FileInputStream中获取文件通道,进行相关写入/读取操作;
package com.pichen.io; import java.nio.*;
import java.nio.channels.*;
import java.io.*; public class GetChannel {
private static final int BSIZE = 1024; public static void main(String[] args) throws Exception {
// 创建文件输出字节流
FileOutputStream fos = new FileOutputStream("data.txt");
//得到文件通道
FileChannel fc = fos.getChannel();
//往通道写入ByteBuffer
fc.write(ByteBuffer.wrap("Some text ".getBytes()));
//关闭流
fos.close(); //随机访问文件
RandomAccessFile raf = new RandomAccessFile("data.txt", "rw");
//得到文件通道
fc = raf.getChannel();
//设置通道的文件位置 为末尾
fc.position(fc.size());
//往通道写入ByteBuffer
fc.write(ByteBuffer.wrap("Some more".getBytes()));
//关闭
raf.close(); //创建文件输入流
FileInputStream fs = new FileInputStream("data.txt");
//得到文件通道
fc = fs.getChannel();
//分配ByteBuffer空间大小
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
//从通道中读取ByteBuffer
fc.read(buff);
//调用此方法为一系列通道写入或相对获取 操作做好准备
buff.flip();
//从ByteBuffer从依次读取字节并打印
while (buff.hasRemaining()){
System.out.print((char) buff.get());
}
fs.close();
}
}
再举个文件复制的例子,有两种方式:
- 打开一个FileChannel用于读,另一个用于写;
- 直接调用transferTo或者transferFrom方法传输通道之间的数据;
如下代码示例:
package com.pichen.io; import java.nio.*;
import java.nio.channels.*;
import java.io.*; public class ChannelCopy {
private static final int BSIZE = 1024; public static void main(String[] args) throws Exception {
//获取文件输入输出字节流
FileInputStream fis = new FileInputStream("C:\\test.jpg");
FileOutputStream fos = new FileOutputStream("C:\\test_copy.jpg"); //从文件输入输出字节流中获取通道
FileChannel fci = fis.getChannel();
FileChannel fco = fos.getChannel();
//分配ByteBuffer空间大小
ByteBuffer buffer = ByteBuffer.allocate(BSIZE); //第一种种数据拷贝方式,直接往输入通道写数据
while (fci.read(buffer) != -1) {
//为写入操作做准备
buffer.flip();
//往输出通道写入buffer
fco.write(buffer);
//清空buffer,重置内部指针
buffer.clear();
} //第二种数据拷贝方式,利用transferTo或者transferFrom方式
FileOutputStream fos2 = new FileOutputStream("C:\\test_copy2.jpg");
FileChannel fco2 = fos.getChannel();
fci.transferTo(0, fci.size(), fco2); fis.close();
fos.close();
fos2.close();
}
}
缓冲区(Buffer)
buffer用于与通道进行交互,举个例子如下,这里以ByteBuffer为例;
package com.pichen.io; import java.nio.*;
import java.nio.channels.*;
import java.io.*; public class GetChannel {
private static final int BSIZE = 1024; public static void main(String[] args) throws Exception { // 随机访问文件
RandomAccessFile raf = new RandomAccessFile("C:\\data.txt", "rw");
// 得到文件通道
FileChannel fc = raf.getChannel(); ByteBuffer bf = ByteBuffer.allocate(BSIZE); int bytesRead = fc.read(bf); // read into buffer.
while (bytesRead != -1) {
// 通过flip()方法将Buffer从写模式切换到读模式
bf.flip();
while (bf.hasRemaining()) {
// 每次读取一个字节
System.out.print((char) bf.get()); } // 清空缓存,准备往缓存写数据
bf.clear();
bytesRead = fc.read(bf);
} // 关闭
raf.close();
}
}
Buffer基本方法
- flip方法:从buffer读数据之前调用,从写模式切换到读模式;
- clear:往buffer写数据之前调用,全部清除;
compact:往buffer写数据之前调用,只清除已读取的数据,新写入的数据会添加到未读数据末尾;
Buffer基本属性
- capacity:buffer空间大小;
- position:读写数据时的指针,指向当前位置;
- limit:读数据时,表示当前可读数据的大小;写数据时,即buffer大小=capacity;
Buffer的类型
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
Buffer中写数据
- 从Channel写到Buffer,调用通道的read
(Bufferbuffer)方法 - put()方法写到Buffer里
,调用Buffer的put方法
Buffer中读取数据
- 从Buffer读取数据到Channel,调用通道的
write(Bufferbuffer)方法 - 使用get()方法从Buffer中读取数据,
调用Buffer的get方法
参考:http://ifeve.com/java-nio-all/
JAVA NIO中的Channels和Buffers的更多相关文章
- Java NIO中核心组成和IO区别
1.Java NIO核心组件 Java NIO中有很多类和组件,包括Channel,Buffer 和 Selector 构成了核心的API.其它组件如Pipe和FileLock是与三个核心组件共同使用 ...
- java NIO中的buffer和channel
缓冲区(Buffer):一,在 Java NIO 中负责数据的存取.缓冲区就是数组.用于存储不同数据类型的数据 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:ByteBufferC ...
- Java NIO中的Buffer 详解
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- Java NIO中的缓冲区Buffer(一)缓冲区基础
什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...
- 转载Java NIO中的Files类的使用
Java NIO中的Files类(java.nio.file.Files)提供了多种操作文件系统中文件的方法. Files.exists() Files.exits()方法用来检查给定的Path在文件 ...
- java NIO中的Reactor相关知识汇总 (转)
一.引子 nio是java的IO框架里边十分重要的一部分内容,其最核心的就是提供了非阻塞IO的处理方式,最典型的应用场景就是处理网络连接.很多同学提起nio都能说起一二,但是细究其背后的原理.思想往往 ...
- Java NIO中的通道Channel(二)分散/聚集 Scatter/Gather
什么是Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道: scatter(分散): ...
- Java NIO中的通道Channel(一)通道基础
什么是通道Channel 这个说实话挺难定义的,有点抽象,不过我们可以根据它的用途来理解: 通道主要用于传输数据,从缓冲区的一侧传到另一侧的实体(如文件.套接字...),反之亦然: 通道是访问IO服务 ...
- JAVA NIO 中的 zerocopy 技术提高IO性能
关于一篇更详细更好的介绍 ZeroCopy技术的文章,可参考:JAVA IO 以及 NIO 理解 这篇文章介绍了 zerocopy技术来提高Linux平台上的IO密集型的JAVA应用程序的性能. ze ...
随机推荐
- 分享几个原生javascript面向对象设计小游戏
一.序言 不知大家是不是和我一样,当初都有个梦想.学编程,就是想开发游戏.结果进入大学学习之后,才知道搞的是数据库应用程序开发!在此,本人就分享下业余时间做的几个小游戏吧!本打算想用winform或w ...
- python3.4怎么连接mysql pymysql连接mysql数据库
本文介绍了python3 4连接mysql数据库的方法,在python3 4中使用原来python2 7的mysqldb已不能连接mysql数据库了,可以使用pymysql. 在python3.4 ...
- MSSQL N张表关联查询
declare @newTime varchar(50); declare @lasetTime varchar(50); set @newTime= getdate(); set @lasetTim ...
- CI框架源码阅读笔记9 CI的自动加载机制autoload
本篇并不是对某一组件的详细源码分析,而只是简单的跟踪了下CI的autoload的基本流程.因此,可以看做是Loader组件的分析前篇. CI框架中,允许你配置autoload数组,这样,在你的应用程序 ...
- MODIS批量处理软件MRT的安装说明
最近在处理遥感影像的时候遇见了MODIS影像数据,从中MOD13中提取NDVI是相当的重要.在一番的百度之中找到了处理modis影像的神器------MRT 接下来我来说明一下MRT的具体安装,如果之 ...
- C# 如何实现带消息数的App图标
上次写了一篇博文,但是每次更新图标时,桌面会闪烁(刷新),有博友说人家的图标都不会刷新,还能动画.我想了一下,如果要达到这个效果,可以用Form来实现,就是在Form中嵌入一个图片,然后用一个labe ...
- knockout源码分析之执行过程
一.执行流程 二.主要类分析 2.1. 在applyBindings中,创建bindingContext,然后执行applyBindingsToNodeAndDescendantsInternal方法 ...
- 使用 WordPress 主题制作的20个精美网页
WordPress 是一款个人博客系统,并逐步演化成一款内容管理系统软件,它是使用 PHP 语言和 MySQL 数据库开发的.用户可以在支持 PHP 和 MySQL 数据库的服务器上使用自己的博客.这 ...
- 你应该知道的10个奇特的 HTML5 单页网站
网页设计师努力寻找新的方式来展现内容.其中一个大的趋势是单页网站,现在被世界上的一些大的品牌广泛采用,使用它们来为用户提供一个快速,干净和简单的而且美丽的网站. 下面是10个令人惊叹的单页 H ...
- about this
var name="window name"; var obj={ name:"obj name", getNameFunc:function(){ //thi ...