FileChannel类的理解和使用(java.nio.channels.FileChannel)

知识点:

1、FileChannel类及方法理解;
2、普通输入输出流复制文件;
3、FileChannel复制文件;
4、新名词记录:{MappedByteBuffer:文件映射在内存的直接换成字节数据;FileLock:代表文件的锁;ByteBuffer:缓存对象}

概述

对于文件的复制,平时我们都是使用输入输出流进行操作,利用源文件创建出一个输入流,然后利用目标文件创建出一个输出流,最后将输入流的数据读取写入到输出流中。这样也是可以进行操作的。但是利用fileChannel是很有用的一个方式。它能直接连接输入输出流的文件通道,将数据直接写入到目标文件中去。而且效率更高。

FileChannel类

FileChannel是一个用读写,映射和操作一个文件的通道。出了读写操作之外,还有裁剪特定大小文件truncate(),强制在内存中的数据刷新到硬盘中去force(),对通道上锁lock()等功能。

他们的使用分别如下面代码:

ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
//读取1024字节内容到byteBuffer钟
fileChannelInput.read(byteBuffer);

解释:上面代码首先创建一个1024大小的缓冲对象,然后在输入通道中读取1024大小数据,放入到缓冲对象中。

byteBuffer.clear();
byteBuffer.put("需要写入的数据".getBytes());
//类似于flush()函数功能,将buffer里面的数据刷新出去
byteBuffer.flip();
//检查是否还有数据未写入
while (byteBuffer.hasRemaining()) fileChannelOutput.write(byteBuffer);

解释:上面的代码是将一段字符串写入到输出文件通道中,因为写入的时候并不保证能一次性写入到文件中,所以需要进行判断是否全部写入,如果没有需要再次调用写入函数操作

//获取文件通道位置
fileChannelInput.position();
fileChannelInput.size();
//截取内容
fileChannelInput.truncate(1024);
//强制刷新数据到硬盘
fileChannelInput.force(true);

解释:上面的代码是获取文件通道的位置和大小。truncate()方法是截取1024大小的数据,指定长度后面的部分将被删除。以及将数据强制刷新到硬盘中,因为系统会将数据先保存在内存中,不保证数据会立即写入到硬盘中,所以有这个需求,就可以直接强制数据写入内存中。

使用

说那么多可能没用,我们还是直接来看看分别使用两种方法进行文件复制的对比。

首先是普通的输入输出流进行复制文件:

/**
* 普通的文件复制方法
*
* @param fromFile 源文件
* @param toFile 目标文件
* @throws FileNotFoundException 未找到文件异常
*/
public void fileCopyNormal(File fromFile, File toFile) throws FileNotFoundException {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(fromFile));
outputStream = new BufferedOutputStream(new FileOutputStream(toFile));
byte[] bytes = new byte[1024];
int i;
//读取到输入流数据,然后写入到输出流中去,实现复制
while ((i = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, i);
  }
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
    }
  }
}

解释:在上面的代码中,传入源文件和目标文件两个参数,然后根据两个文件,分别出具输入输出流,然后将输入流的数据读取,并且写入输出流中,就完成了文件的复制操作。

下面再看一下利用fileChannel进行文件的复制操作。

/**
* 用filechannel进行文件复制
*
* @param fromFile 源文件
* @param toFile 目标文件
*/
public void fileCopyWithFileChannel(File fromFile, File toFile) {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
FileChannel fileChannelInput = null;
FileChannel fileChannelOutput = null;
try {
fileInputStream = new FileInputStream(fromFile);
fileOutputStream = new FileOutputStream(toFile);
//得到fileInputStream的文件通道
fileChannelInput = fileInputStream.getChannel();
//得到fileOutputStream的文件通道
fileChannelOutput = fileOutputStream.getChannel();
//将fileChannelInput通道的数据,写入到fileChannelOutput通道
fileChannelInput.transferTo(0, fileChannelInput.size(), fileChannelOutput);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null)
fileInputStream.close();
if (fileChannelInput != null)
fileChannelInput.close();
if (fileOutputStream != null)
fileOutputStream.close();
if (fileChannelOutput != null)
fileChannelOutput.close();
} catch (IOException e) {
e.printStackTrace();
    }
  }
}

解释:上面代码中,也是先分别创建了两个文件的输入输出流,然后在分别获取到两个文件的文件通道,然后将源文件的文件通道直接和目标文件的文件通道进行连接,直接将数据写入到目标文件中区。不需要进行分别的读取和写入操作了。

运行代码之后,复制一个文件,对比两种复制方法,发现利用filechannel使用的时间比普通的读取输入时间缩短了将近一半。尤其是在进行大文件复制的时候,filechannel显得更加有优势。这里就不贴出图片了。见谅!

总结

这里我们了解了FileChannel类,知道了它所具有的特点和功能,那么我们就可以好好的使用它了。尤其是在我们复制文件的时候,可以更好的利用这个类,可以提高效率,也可以防止出现oom等其它情况。

以上就是所有内容,如有任何问题,请及时留言与我联系。(博客:http://www.cnblogs.com/yjd_hycf_space/

FileChannel类的理解和使用的更多相关文章

  1. NIO之FileChannel类的理解和使用

    文章链接:http://blog.csdn.net/qq_16628781/article/details/70532307 知识点: FileChannel类及方法理解: 普通输入输出流复制文件: ...

  2. [BS-18] 对OC中不可变类的理解

    对OC中不可变类的理解 OC中存在很多不可变的类(如NSString,NSAttributedString,NSArray,NSDictionary,NSSet等),用它们创建的对象存在于堆内存中,但 ...

  3. 对Java中properties类的理解

    转载于:https://www.cnblogs.com/bakari/p/3562244.html 一.Java Properties类 Java中有个比较重要的类Properties(Java.ut ...

  4. AtomicInteger类的理解与使用

    AtomicInteger类的理解与使用 首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Sample1 { private stati ...

  5. JavaScript es6 class类的理解。

    本着互联网的分享精神,在本篇文章我将会把我对JavaScript  es6 class类的理解分享给大家. JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖. 类语法 ...

  6. PHP反射类的理解(代码篇)

    <?php/** * Created by PhpStorm. * User: * Date: 2017/6/12 * Time: 14:34 * 关于反射类的理解 */class Person ...

  7. java 面向对象(三十八):反射(二) Class类的理解与获取Class的实例

    1.Class类的理解 1.类的加载过程:程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾).接着我们使用java.exe命令对某个字节码文件进行解释运行.相当于将某个 ...

  8. java常用类,包装类,String类的理解和创建对象以及StringBuilder和StringBuffer之间的区别联系

    一.包装类的分类: 1.黄色部分的父类为Number 继承关系: Boolean Character 其他六个基本数据类型 2.装箱和拆箱 理解:一个例子,其他的都相同 装箱:Integer inte ...

  9. Python无类再理解--metaclass,type

    上次理解过一次,时间久了,就忘了.. 再学习一次.. http://blog.jobbole.com/21351/ ======================= 但是,Python中的类还远不止如此 ...

随机推荐

  1. C#基础第二天-作业答案-九九乘法表-打印星星

    题一:九九乘法表的答案 //正三角 ; i < ; i++) { ; j <= i; j++) { Console.Write("{0}*{1}={2} ", j, i ...

  2. 转:zTree树控件扩展篇:巧用zTree控件实现文本框输入关键词自动模糊查找zTree树节点实现模糊匹配下拉选择效果

    是否可以借助于zTree实现文本框输入关键词自动模糊匹配zTree下拉树,然后选择下拉树内节点显示在文本框内且隐藏下拉树. 看到这个需求脑子里头大致已经想到了要如何实现这样一个需求,当时是限于时间问题 ...

  3. 基于数据库构建分布式的ID生成方案

    在分布式系统中,生成全局唯一ID,有很多种方案,但是在这多种方案中,每种方案都有有缺点,下面我们之针对通过常用数据库来生成分布式ID的方案,其它方法会在其它文中讨论: 1,RDBMS生成ID: 这里我 ...

  4. MongoDB联合查询 -摘自网络

    1.简单手工关联 首先将结果查询出来放到一个变量里面,然后再查询 u = db.user.findOne({author:"wangwenlong"}); for(var p = ...

  5. 两种屏幕HUD区域限制的做法(矩形,弧形)

    HUD区域限制算是比较常用到的功能,方形的HUD区域限制多见于小地图,弧形或者椭圆多见于屏幕范围约束. 我没有研究倒角矩形做法,而是将椭圆和矩形进行插值得到一个弧度比较高的形状: 当插值为0时限制范围 ...

  6. ASP.NET MVC做的微信WEBAPP中调用微信JSSDK扫一扫

    今天做一个项目,是在微信上用的,微信WEB APP,里面用到了调用手机摄像头扫一扫二维码的功能,记得以前某个项目里写有的,但是找不到之前那个项目源码了,想复制粘贴也复制不了了,只好对着微信的那个开发文 ...

  7. Mac OSX 快捷键&命令行

    一.Mac OSX 快捷键 ctrl+shift                                    快速放大dock的图标会暂时放大,而如果你开启了dock放大Command+Op ...

  8. Windows系统环境变量path优先级测试报告

    转自:http://bluekylin.cnblogs.com/archive/2005/12/16/298797.html 总以为自己很已经会操作windows了,今天在它帮助中看到一大片还不知道的 ...

  9. NGINX宏观手记(变量|配置)

    前言 任何一个工具都有它的灵魂所在,作为一个PHP程序员,我们可能仅仅使用了它的一小部分,这篇文章让你更加了解Nginx,本章大多都是总结.翻译.整理 ,希望你可以知道nginx不仅仅是PHP的附属品 ...

  10. innobackupex在线备份及恢复(全量和增量)

    Xtrabackup是由percona开发的一个开源软件,它是innodb热备工具ibbackup(收费的商业软件)的一个开源替代品.Xtrabackup由个部分组成:xtrabackup和innob ...