java-NIO-FileChannel(文件IO)
Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。
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大小的数据,指定长度后面的部分将被删除。以及将数据强制刷新到硬盘中,因为系统会将数据先保存在内存中,不保证数据会立即写入到硬盘中,所以有这个需求,就可以直接强制数据写入内存中。
使用
说那么多可能没用,我们还是直接来看看分别使用两种方法进行文件复制的对比。
首先是普通的输入输出流进行复制文件:
import org.springframework.util.ResourceUtils; import java.io.*; /**
* 普通的文件复制
*/
public class FileCopyForNomal {
public void fileCopy(File fromFile,File toFile){
InputStream inputStream = null;
OutputStream outputStream = null; try {
inputStream = new BufferedInputStream(new FileInputStream(fromFile));
outputStream = new BufferedOutputStream(new FileOutputStream(toFile,true));//追加
byte [] bytes = new byte[1024];
int i;
while((i=inputStream.read(bytes)) != -1){
outputStream.write(bytes,0,i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(inputStream!=null){
inputStream.close();
}if(outputStream!=null){
outputStream.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
} public static void main(String[] args) throws FileNotFoundException {
String from = ResourceUtils.getFile("classpath:a.txt").getPath();//这边文件是在target下
System.out.println(from);
String to = ResourceUtils.getFile("classpath:b.txt").getPath();//这边文件是在target下
System.out.println(to);
File fromFile = new File(from);
File toFile = new File(to); Long startTime = System.currentTimeMillis();
new FileCopyForNomal().fileCopy(fromFile,toFile);
Long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
}
}
结果:
G:\idea_workspace\io\filechannel\target\classes\a.txt
G:\idea_workspace\io\filechannel\target\classes\b.txt
48
下面再看一下利用fileChannel进行文件的复制操作。
import org.springframework.util.ResourceUtils; import java.io.*;
import java.nio.channels.FileChannel; /**
* 通道文件复制
*/
public class FileCopyForChannel {
public void fileCopy(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通道的数据,写入到fileOutputStream中
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();
}
}
} public static void main(String[] args) throws FileNotFoundException {
String from = ResourceUtils.getFile("classpath:a.txt").getPath();//这边文件是在target下
System.out.println(from);
String to = ResourceUtils.getFile("classpath:b.txt").getPath();//这边文件是在target下
System.out.println(to);
File fromFile = new File(from);
File toFile = new File(to); Long startTime = System.currentTimeMillis();
new FileCopyForChannel().fileCopy(fromFile,toFile);
Long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
}
}
结果:
G:\idea_workspace\io\filechannel\target\classes\a.txt
G:\idea_workspace\io\filechannel\target\classes\b.txt
22
运行代码之后,复制一个文件,对比两种复制方法,发现利用filechannel使用的时间比普通的读取输入时间缩短了将近一半。尤其是在进行大文件复制的时候,filechannel显得更加有优势。
总结
这里我们了解了FileChannel类,知道了它所具有的特点和功能,那么我们就可以好好的使用它了。尤其是在我们复制文件的时候,可以更好的利用这个类,可以提高效率,也可以防止出现oom等其它情况。
源码地址:https://github.com/qjm201000/io_nio_filechannel.git
java-NIO-FileChannel(文件IO)的更多相关文章
- Java NIO FileChannel
A Java NIO FileChannel is a channel that is connected to a file. Using a file channel you can read d ...
- JAVA NIO FileChannel 内存映射文件
文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...
- Java IO和Java NIO在文件拷贝上的性能差异分析
1. 在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...
- 【原创】java NIO FileChannel 学习笔记 FileChannel 简介
java NIO 中FileChannel 的实现类是 FileChannelImpl,FileChannel本身是一个抽象类. 先介绍FileChannel File Channels 是线程安全 ...
- JAVA NIO之文件通道
1.简介 通道是 Java NIO 的核心内容之一,在使用上,通道需和缓存类(ByteBuffer)配合完成读写等操作.与传统的流式 IO 中数据单向流动不同,通道中的数据可以双向流动.通道既可以读, ...
- Java NIO 读取文件、写入文件、读取写入混合
前言 Java NIO(new/inputstream outputstream)使用通道.缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position).限制(limi ...
- java nio 映射文件内容到内存
FileChannel 的一个最好的功能就是能将文件的某个部分直接映射到内存.这要感谢 FileChannel.map() 方法,这个方法有下面三个参数: mode:映射到内存需要指定下面三种模式之一 ...
- java输入输出 -- java NIO之文件通道
一.简介 通道是 Java NIO 的核心内容之一,在使用上,通道需和缓存类(ByteBuffer)配合完成读写等操作.与传统的流式 IO 中数据单向流动不同,通道中的数据可以双向流动.通道既可以读, ...
- 3,Java中的文件IO流
1,File类 ··· 概念:File对象可以表示一个文件或目录.可以对其进行增删改查. ··· 常用方法: File f = new File("."); 判断是 ...
- Java NIO.2 —— 文件或目录移动操作
移动文件树是复制和删除的文件树的结合.实际上,有两种方式来完成文件的移动.一种是使用Files.move(), Files.copy(), 和Files.delete() 这三个方法:另一种是只使用F ...
随机推荐
- ./configure,make,make install的作用(configure一般用来生成 Makefile,相当于qmake)
这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC ...
- ORACLE 时间加减操作
DATE和timestamp类型都可以进行加减操作.可以对当前日期加年.月.日.时.分.秒,操作不同的时间类型,有三种方法: 1 使用内置函数numtodsinterval增加小时,分钟和秒2 加一个 ...
- ASP .NET Controller返回类型
返回类型 return View(model); 即返回htmlreturn Json("String"); 返回Json格式的数据return File(new byte[] { ...
- VS2012发布到XP平台
默认情况下,你的VS2012工程发布后,在XP下运行会出现提示“not a valid win32 application”. 微软推出了Visual Studio 2012 update 1可以支持 ...
- mingw64 构建 Geos
简述 在做某个小程序时候用到了QT,而用的Qt是mingw版本的,所以使用mingw构建了一下geos库. 1.准备工作 首先需要先安装好mingw,这里直接使用http://www.mingw-w6 ...
- 使用Visual Studio Code创建第一个ASP.NET Core应用程序
全文翻译自:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 这篇文章将向你展示如何在Mac上写出你的第一个A ...
- UWP开发-自适应布局
了解css的人知道,对于不同的屏幕尺寸,css使用一种名为媒体查询的东东来适用不同的屏幕尺寸,以提升用户体验.当用户使用PC等大屏幕的设备时,网页将呈现一种布局形式:而当用户使用手机等小屏幕设备时,布 ...
- QToolBar也是QWidget,可以放在QWidget的中间
可以试着把左边做成一个widget.从上到下依次为:QTextEditQToolBarQTextEdit然后再对她们进行垂直布局(布局是具体需求而定).代码大致如下: TCenterWidget::T ...
- 年度调查 看看 2016 年 Go 语言调查结果
Go 语言官方博客公布了 2016 年 Go 语言使用调查. 在 3,595 名被调查者中,89% 称他们在工作中或工作之外用 Go 编程:63% 称他们的工作是 Web 开发,但只有 9% 的人只从 ...
- 解决xp越来越慢的办法(其中有些自动备份的功能)
1.减少磁盘空间占用2.终止不常用的系统服务3.安全问题4.另外一些技巧 首先问一下,你是不是很想激活XP,不...准确的说你是不是想在ms的站上能够升级.如果答案是肯定的话,那我们就先来探讨一下安装 ...