一、创建一个大文件

下载文件时往往会创建一个指定大小的空文件

package com.lazy.nio;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

/**

* 创建大文件

* @author Lazy Gene

*

*/

public class FileCreator {

public static void main(String[] args) {

FileCreator creator = new FileCreator();

creator.createBigEmptyFile();

}

void createBigEmptyFile(){

Path filePath = Paths.get("from/test.tmp");

// 这段代码实际上可以在FIleChannel 调用open方式时指定OpenOption 为Create_NEW

try {

if (!Files.exists(filePath)) {

Files.createFile(filePath);

}

} catch (IOException e1) {

e1.printStackTrace();

}

//写一个字节

ByteBuffer buffer = ByteBuffer.allocate(1);

try (FileChannel fileChannel = FileChannel.open(filePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {

fileChannel.position(2L << 32 - 1); //移动位置, 生成一个4G的空文件

fileChannel.write(buffer);

} catch (IOException e) {

e.printStackTrace();

}

}

}

二、文件转移

NIO 提供transferTo tansferFrom, 和传统的文件访问方式相比减少了数据从内核到用户空间的复制,数据直接在内核移动,在Linux系统中使用sendfile系统调用

这里分别通过FileChannel.transferFrom 和Files.copy以及普通的io调用实现文件的复制

package com.lazy.nio;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.channels.FileChannel;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

/**

* 文件转移

*

* @author Lazy Gene(ljgeng@iflytek.com)

*

*/

public class FileTransfer {

Path fromPath = Paths.get("from/test.tmp");

Path toPath = Paths.get("to/test.tmp");

public static void main(String[] args) throws IOException {

FileTransfer transfer = new FileTransfer();

long start = System.currentTimeMillis();

transfer.transferFrom();

long end1 = System.currentTimeMillis();

System.out.println("transferFrom: "+ (end1 - start));

Files.deleteIfExists(transfer.toPath);

transfer.copy();

long end2 = System.currentTimeMillis();

System.out.println("Files copy: "+(end2 - end1));

Files.deleteIfExists(transfer.toPath);

transfer.ioCopy();

long end3 = System.currentTimeMillis();

System.out.println("original io: "+(end3 - end2));

}

void transferFrom() {

try (FileChannel channelFrom = FileChannel.open(fromPath, StandardOpenOption.READ);

FileChannel channelTo = FileChannel.open(toPath, StandardOpenOption.CREATE_NEW,

StandardOpenOption.WRITE);) {

channelTo.transferFrom(channelFrom, 0L, channelFrom.size());

} catch (IOException e) {

e.printStackTrace();

}

}

void copy() {

try {

Files.copy(fromPath, toPath);

} catch (IOException e) {

e.printStackTrace();

}

}

void ioCopy() {

try (InputStream is = new FileInputStream(fromPath.toFile());

OutputStream os = new FileOutputStream(toPath.toFile());) {

byte[] buffer = new byte[4096];

int byteread = 0;

while ((byteread = is.read(buffer)) != -1) {

os.write(buffer, 0, byteread);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

执行结果

transferFrom: 32726

Files copy: 33002

original io: 112975

将ioCopy方法中每次读取字节数调大十倍和百倍后结果

original io: 54743 (十倍)

original io: 93110 (百倍)

三、FileChannel.map 的使用

FileChannel.map 将文件按照一定大小块映射到内存区域,程序方式内存区域操作文件,适合大文件只读操作,如大文件的md5校验。

package com.lazy.nio;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.nio.channels.FileChannel;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

/**

* 使用介绍

* @author Lazy Gene

*

*/

public class FileChannelMap {

public static void main(String[] args) throws NoSuchAlgorithmException, IOException {

// 计算test.tmp 的md5值,将文件分成多块计算

Path path = Paths.get("from/test.tmp");

File file = path.toFile();

RandomAccessFile accessFile = new RandomAccessFile(file, "r");

MessageDigest MD5 = MessageDigest.getInstance("MD5");

long start = System.currentTimeMillis();

long eachSize = 1024 * 1024L;

long length = file.length();

int count = 1 + (int) (length / eachSize); //分块数量

long remaining = length; // 剩下的大小

for (int i=0;i

MD5.update(accessFile.getChannel().map(FileChannel.MapMode.READ_ONLY, i * eachSize, Math.min(remaining, eachSize)));

remaining -= eachSize;

}

accessFile.close();

long end = System.currentTimeMillis();

System.out.println("用时:"+(end - start));

System.out.println("md5: "+ new String(Hex.encodeHex(MD5.digest())));

//方法二

MessageDigest new_MD5 = MessageDigest.getInstance("MD5");

FileInputStream in=new FileInputStream(file);

byte[] buffer=new byte[65536];

int rv=0;

while((rv=in.read(buffer))>0) {

new_MD5.update(buffer,0,rv);

}

long end1 = System.currentTimeMillis();

in.close();

System.out.println("用时:"+(end1 - end));

System.out.println("io md5: "+ new String(Hex.encodeHex(new_MD5.digest())));

}

}

对于4g文件运行结果:

用时:15172

md5: f18c798ff5d450dfe4d3acdc12b621ff

用时:15811

io md5: f18c798ff5d450dfe4d3acdc12b621ff

差别不大呀,将文件调到16g,运行结果

用时:65046

md5: 0eb76b1bf69255feec7bdf4a3b5e2805

用时:62697

io md5: 0eb76b1bf69255feec7bdf4a3b5e2805

这里只所以差别不大,估计是应用map操作和操作系统的底层io实现相关,下次换成linux看看。

java nio 文件_Java nio 的文件处理相关推荐

  1. java bytebuffer 读写_java nio bytebuffer文件读写问题

    为什么下面的代码从文件中读不出3和2来?importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOExc ...

  2. java 复制文件_Java中复制文件的4种方法

    Java拷贝文件是一种非常常见的操作.但是java.io.File类没有任何快捷方法可以将文件从源复制到目标文件.在这里,我们将了解学习可以在java中复制文件的四种不同方法. 方法一:使用Strea ...

  3. java nio教程_Java NIO教程

    java nio教程 1.简介 Java NIO是Java 1.4引入的一个库. 自从Java NIO推出以来,它提供了另一种方法来处理I / O和网络事务. 它被认为是Java网络和Java IO库 ...

  4. java wav 切割_java切割音频文件

    工具: 一个jar包即可:jave-1.0.2.jar 可以切割wav格式的音频文件 完整工程目录 就一个jar包,一个main类 代码: package com.zit; import java.i ...

  5. java 创建新文件_Java创建新文件

    创建文件是一种非常常见的IO操作,在这一小节中我们将学习如何在java中创建文件的几个方法. 在java中创建文件有三种流行的方法,下面将一个一个地来学习. 方法一:使用File.createNewF ...

  6. JAVA编程TXT文件_java读写txt文件的方法

    java读写txt文件的方法 发布时间:2020-06-26 15:54:02 来源:亿速云 阅读:111 作者:Leah 本篇文章为大家展示了java读写txt文件的方法,代码简明扼要并且容易理解, ...

  7. java中怎么剪切文件_java中实现文件复制、剪切和删除

    import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...

  8. java 快速读文件_java快速读取文件

    如何优雅读取文件,java想简单读写一个文件都要上10行代码.幸好guava和apache commons 都有提供简单操作文件工具. 简单介绍读取文件最后一行.读取文件第一行.读取大文件.往大文件追 ...

  9. java代码如何删除文件_Java如何删除文件和目录代码? 爱问知识人

    package book.io; import java.io.File; /** * * @author XWZ * 2007-11-27 * 删除文件或目录 */ public class Del ...

最新文章

  1. SharedPreferences源码解析
  2. 超级计算机和人比,和超级计算机相比,人类的大脑很弱吗
  3. python按键盘上哪个键运行_python根据键盘输入进行相应操作
  4. MySQL数据库面试题
  5. 福师2018计算机应用基础,中石油华东《计算机应用基础》2018年秋学期在线作业100分答案满分...
  6. python与数据库完整项目_python入门:操作数据库项目实例分享
  7. 几种ELK常见的架构模式
  8. 利用c#反射提高设计灵活性
  9. 如何刷新linux的fdisk,②linux fdisk
  10. Azkaban Flow 2.0的使用
  11. Firefox OS开发指南
  12. AFX_EXT_CLASS的使用
  13. 树莓派3B+新麦克风调试
  14. STM32使用外设热敏打印机进行打印
  15. 域服务器文件备份,怎么备份域服务器?
  16. 中国证券市场之[主板、中小板、创业板、科创板、新三板]
  17. mac电脑如何导入ps笔刷 ,Adobe Photoshop笔刷导入安装教程详解
  18. Mr.Xiong使用jQuery从控制器获取数据
  19. 不存在从“int” 转换到“ListNode”的适当构造函数 错误解决方法
  20. JavaScript软件

热门文章

  1. Bootstrap的坑--千万别踩
  2. Error: Network is unreachable. Reason: couldn‘t connect to server localhost:27017(连接mongodb数据库失败)
  3. 川崎焊接机器人编程实例_机器人现场编程-川崎机器人示教-综合命令.pptx
  4. arm中断保护和恢复_ARM中断返回的详细分析
  5. mysql当数据改变时_MySQL中,当update修改数据与原数据相同时会再次执行吗?
  6. 【Redis系列】深入浅出Redis主从复制之哨兵模式【实践】
  7. From Hero to Zero
  8. android与html注册登录,Android登录注册源码
  9. mybatis-plus与jpa在操作数据库时写法对比
  10. JavaScript高级day01-AM【WebStrom安装、数据类型分类及判断、数据-内存-变量、引用变量赋值、对象的组成】