FileChannel原理
官方对Channel的解释

(一个用于输入/输出操作的连接。通道表示对实体的开放连接,如硬件设备、文件、网络套接字或能够执行一个或多个不同的输入/输出操作的程序组件,例如读取或写入。)
Thanking In Java中的描述

Channel是对I/O操作的封装。
FileChannel配合着ByteBuffer,将读写的数据缓存到内存中,然后以批量/缓存的方式read/write,省去了非批量操作时的重复中间操作,操纵大文件时可以显著提高效率(和Stream以byte数组方式有什么区别?经过测试,效率上几乎无区别)。
不过对于运行在容器中的应用需要考虑GC,而ByteBuffer可以使用直接内存(系统内存)(allocateDirect),使用后无需jvm回收。
ByteBuffer还有一个子类MappedByteBuffer可以直接将文件映射到操作系统的虚拟内存,读写文件速度会更快,参考https://www.cnblogs.com/lyftest/p/6564282.html。
FileChannel和Stream的使用方式和效率对比代码
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.time.Duration;
import java.time.Instant; public class FileChannelTest { public static void main(String[] args) {
// 4GB的数据
File sourceFile = new File("d://dd.iso");
File targetFile = new File("d://ee.iso");
targetFile.deleteOnExit();
try {
targetFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
} // stream方式
FileChannelTest.copyFileByStream(sourceFile, targetFile); // channel方式
// FileChannelTest.copyFileByFileChannel(sourceFile, targetFile);
} /**
* channel方式
*
* @param sourceFile
* @param targetFile
*/
public static void copyFileByFileChannel(File sourceFile, File targetFile) {
Instant begin = Instant.now(); RandomAccessFile randomAccessSourceFile;
RandomAccessFile randomAccessTargetFile;
try {
// 构造RandomAccessFile,用于获取FileChannel
randomAccessSourceFile = new RandomAccessFile(sourceFile, "r");
randomAccessTargetFile = new RandomAccessFile(targetFile, "rw");
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
} FileChannel sourceFileChannel = randomAccessSourceFile.getChannel();
FileChannel targetFileChannel = randomAccessTargetFile.getChannel(); // 分配1MB的缓存空间
ByteBuffer byteBuffer = ByteBuffer.allocate( * );
try {
while (sourceFileChannel.read(byteBuffer) != -) {
byteBuffer.flip();
targetFileChannel.write(byteBuffer);
byteBuffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
sourceFileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
targetFileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
} System.out.println("total spent " + Duration.between(begin, Instant.now()).toMillis());
} /**
* stream方式
*
* @param sourceFile
* @param targetFile
*/
public static void copyFileByStream(File sourceFile, File targetFile) {
Instant begin = Instant.now(); FileInputStream fis;
FileOutputStream fos;
try {
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
// 使用byte数组读取方式,缓存1MB数据
byte[] readed = new byte[ * ];
try {
while (fis.read(readed) != -) {
fos.write(readed);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
} System.out.println("total spent " + Duration.between(begin, Instant.now()).toMillis());
}
}
FileChannel原理的更多相关文章
- Java NIO使用及原理分析(1-4)(转)
转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...
- flume原理及代码实现
转载标明出处:http://www.cnblogs.com/adealjason/p/6240122.html 最近想玩一下流计算,先看了flume的实现原理及源码 源码可以去apache 官网下载 ...
- Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer
Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer 1. Java NIO(New Input/Output)1 1.1. 变更通知(因为每个事件都需要一个监听者 ...
- Java NIO原理分析
Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构.一种简单而又直接的解决方案是“one-th ...
- Java NIO使用及原理分析(二)
在第一篇中,我们介绍了NIO中的两个核心对象:缓冲区和通道,在谈到缓冲区时,我们说缓冲区对象本质上是一个数组,但它其实是一个特殊的数组,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况,如 ...
- Lucene 的索引文件锁原理
Lucene 的索引文件锁原理 2016/11/24 · IT技术 · lucene 环境 Lucene 6.0.0Java “1.8.0_111”OS Windows 7 Ultimate 线程 ...
- JAVA NIO工作原理及代码示例
简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...
- 全面解读Java NIO工作原理(3)
全面解读Java NIO工作原理(3) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- 全面解读Java NIO工作原理(1)
全面解读Java NIO工作原理(1) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
随机推荐
- zencart模板列表下载地址
下载index.html文件后用浏览器打开,里面有一百多个zencart模板示例 下载地址:zencart模板示例下载地址 或者复制下面网址,用浏览器打开即可下载: http://bcs.duapp. ...
- 火狐插件simple timer 定时打开指定网页
今天我要介绍的是火狐浏览器一款插件:Simple Timer,该插件是火狐一个可以添加计时器和定时提醒功能插件,该插件的主要作用就是当你的设置在某一个时刻提醒时,插件会自动弹出通知,并且自动打开你想要 ...
- 第三次java测验2
package java3; public class Suiji { public long a=12345L;//定义long类型的a,b,c变量 public long c=12345L; pu ...
- oracle表的列合并(group by)和行合并(union all)
group by select a.dn,t.dn dnt,a.BEGIN_TIME,a.R032_001,t.R032_001,a.R032_002,a.R032_003,a.R032_004, a ...
- 基于idea的maven(一)Maven的安装
1.Maven前置依赖 检查电脑是是否安装java 2.下载maven 网址 www.apache.org 解压 maven 压缩包, 并创建相应的maven本地仓库的路径. 打开 conf文件夹中 ...
- qt5--字符串格式拼接
QString str=QString("x坐标为:%1 y坐标为:%2").arg(i).arg(j);
- python连接mysql操作(1)
python连接mysql操作(1) import pymysql import pymysql.cursors # 连接数据库 connect = pymysql.Connect( host='10 ...
- centos7安装android studio遇到Unable to run mksdcard sdk tool
centos系统为最小化安装,所以安装新软件时缺少许多依赖包,Android Studio下载的mksdcard是32位的,而系统是64位的,所以需要安装支持32位软件的依赖包. sudo yum i ...
- C语言 - strlen的编程实现及总结
一.函数strlen的编程实现 1.strlen函数的实现 原型: size_t strlen(const char *str); 头文件:#include <string.h> 功能:计 ...
- HGOI 20190821 慈溪一中互测
Problem A 给出一个$n$个点$m$条边的仙人掌图(每条边最多处于一个简单环中). 使用$c$种颜色对这张图中的顶点染色,使得每一条无向边连接的两个点颜色不同. 求染色的方案数,$mod \ ...