目前Java中最IO有多种文件读取的方法,本文章对比Stream,NIO ByteBuffer,NIO MappedByteBuffer的性能,让我们知道到底怎么能写出性能高的文件读取代码。

  1. package com.seeyon.nio;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.io.*;
  6. import java.nio.ByteBuffer;
  7. import java.nio.MappedByteBuffer;
  8. import java.nio.channels.FileChannel;
  9.  
  10. /**
  11. * Created by yangyu on 16/12/28.
  12. */
  13.  
  14. /**
  15. * 比较Stream流,NIO ByteBuffer,NIO MappedByteBuffer性能对比
  16. * 其中Stream最慢,NIO MappedByteBuffer最快
  17. * Stream:1000ms
  18. * NIO ByteBuffer:220ms
  19. * NIO MappedByteBuffer:112ms
  20. */
  21. public class Compare {
  22.  
  23. /**
  24. * 使用stream作为IO流读取和写入文件
  25. * 速度:1000ms左右
  26. *
  27. * @throws IOException
  28. */
  29. @Test
  30. public void useStream() throws IOException {
  31.  
  32. long startTime = System.currentTimeMillis();
  33. /**
  34. * 4000000个整数长度的文件
  35. */
  36. int num = 2000 * 2000;
  37.  
  38. /**
  39. * 带缓冲的输出流,写文件
  40. */
  41. DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("/Users/yangyu/Downloads/compare.tmp")));
  42. for (int i = 0; i < num; i++) {
  43. dataOutputStream.writeInt(i);
  44. }
  45. dataOutputStream.close();
  46.  
  47. int data = 0;
  48. /**
  49. * 带缓冲的输入流,读文件
  50. */
  51. DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("/Users/yangyu/Downloads/compare.tmp")));
  52. try {
  53. while (true) {
  54. data = in.readInt();
  55. }
  56. } catch (EOFException e) {
  57. System.out.println("读取完成"+data);
  58. }
  59. in.close();
  60. long endTime = System.currentTimeMillis();
  61. System.out.println("ms:" + (endTime - startTime));
  62. }
  63.  
  64. /**
  65. * 使用NIO ByteBuffer
  66. * 时间:220ms
  67. * @throws IOException
  68. */
  69. @Test
  70. public void useNioByteBuffer() throws IOException {
  71. long startTime = System.currentTimeMillis();
  72. int num = 2000*2000;
  73. /**
  74. * 文件输出流
  75. */
  76. FileOutputStream fileOutputStream = new FileOutputStream("/Users/yangyu/Downloads/compare.tmp");
  77. /**
  78. * NIO Channel 通道
  79. */
  80. FileChannel fileChannel = fileOutputStream.getChannel();
  81. /**
  82. * ByteBuffer缓冲区
  83. */
  84. ByteBuffer buffer = ByteBuffer.allocate(num*5);
  85. for (int i = 0; i < num; i++) {
  86. buffer.putInt(i);
  87. }
  88. /**
  89. * 为写做准备
  90. */
  91. buffer.flip();
  92. /**
  93. * 写操作
  94. */
  95. fileChannel.write(buffer);
  96. fileChannel.close();
  97.  
  98. /**
  99. * 缓冲区
  100. */
  101. ByteBuffer buffer1 = ByteBuffer.allocate(num*5);
  102. /**
  103. * 文件输入流
  104. */
  105. FileInputStream in = new FileInputStream("/Users/yangyu/Downloads/compare.tmp");
  106. /**
  107. * 输入通道
  108. */
  109. FileChannel fin = in.getChannel();
  110. /**
  111. * 为读取做准备
  112. */
  113. buffer1.clear();
  114. System.out.println(buffer1.limit());
  115. /**
  116. * 读取
  117. */
  118. fin.read(buffer1);
  119. fin.close();
  120.  
  121. long endTime = System.currentTimeMillis();
  122. System.out.println("ms:" + (endTime - startTime));
  123. buffer1.flip();
  124. System.out.println(buffer1.limit());
  125. }
  126.  
  127. /**
  128. * 使用MappedByteBuffer,通过FileChannel将文件映射到内存
  129. * 时间:112ms
  130. * @throws IOException
  131. */
  132. @Test
  133. public void useRandomAccess() throws IOException {
  134. long startTime = System.currentTimeMillis();
  135. int num = 2000*2000;
  136.  
  137. /**
  138. * 使用可随机访问位置的RandomAccessFile
  139. */
  140. RandomAccessFile file = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
  141. /**
  142. * 获取通道Channel
  143. */
  144. FileChannel fileChannel = file.getChannel();
  145. /**
  146. * 将文件映射到缓冲区MappedByteBuffer
  147. */
  148. MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,num*4);
  149. /**
  150. * 写文件
  151. */
  152. for (int i = 0; i < num; i++) {
  153. mappedByteBuffer.putInt(i);
  154. }
  155. fileChannel.close();
  156.  
  157. int data=0;
  158. RandomAccessFile file1 = new RandomAccessFile("/Users/yangyu/Downloads/compare.tmp","rw");
  159. FileChannel fc = file1.getChannel();
  160. MappedByteBuffer mappedByteBuffer1 = fc.map(FileChannel.MapMode.READ_WRITE,0,file1.length());
  161. /**
  162. * 读文件
  163. */
  164. while (mappedByteBuffer1.hasRemaining()){
  165. data = mappedByteBuffer1.getInt();
  166. }
  167. fc.close();
  168. long endTime = System.currentTimeMillis();
  169. System.out.println("ms:" + (endTime - startTime));
  170. System.out.println(data);
  171. }
  172. }

结论非常明显啦,以后再使用IO读写文件的时候,多使用NIO MappedByteBuffer吧,毕竟NIO比老IO性能好太多啦。

Java--Stream,NIO ByteBuffer,NIO MappedByteBuffer性能对比的更多相关文章

  1. NIO与普通IO文件读写性能对比

    最近在熟悉java的nio功能.nio采用了缓冲区的方式进行文件的读写,这一点更接近于OS执行I/O的方式.写了个新旧I/O复制文件的代码,练练手,顺便验证一下两者读写性能的对比,nio是否真的比普通 ...

  2. java.nio.ByteBuffer中的flip()、rewind()、compact()等方法的使用和区别

    java.nio.ByteBuffer 1. ByteBuffer中的参数position.limit.capacity.mark含义: position:表示当前指针的位置(下一个要操作的数据元素的 ...

  3. 5种调优Java NIO和NIO.2的方式

    Java NIO(New Input/Output)——新的输入/输出API包——是2002年引入到J2SE 1.4里的.Java NIO的目标是提高Java平台上的I/O密集型任务的性能.过了十年, ...

  4. Java的BIO,NIO,AIO

    Java中的IO操作可谓常见.在Java的IO体系中,常有些名词容易让人困惑不解.为此,先通俗地介绍下这些名词. 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同 ...

  5. 顺序、随机IO和Java多种读写文件性能对比

    概述 对于磁盘的读写分为两种模式,顺序IO和随机IO. 随机IO存在一个寻址的过程,所以效率比较低.而顺序IO,相当于有一个物理索引,在读取的时候不需要寻找地址,效率很高. 基本流程 总体结构 我们编 ...

  6. Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer

    Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer 1. Java NIO(New Input/Output)1 1.1. 变更通知(因为每个事件都需要一个监听者 ...

  7. Java NIO、NIO.2学习笔记

    相关学习资料 http://www.molotang.com/articles/903.html http://www.ibm.com/developerworks/cn/education/java ...

  8. 【转载】Java NIO学习 & NIO BIO AIO 比较

    可以参考这个页面: http://www.iteye.com/magazines/132-Java-NIO (下面这个页面也有) http://ifeve.com/overview/ 另,在这篇文章里 ...

  9. java学习-NIO(五)NIO学习总结以及NIO新特性介绍

    我们知道是NIO是在2002年引入到J2SE 1.4里的,很多Java开发者比如我还是不知道怎么充分利用NIO,更少的人知道在Java SE 7里引入了更新的输入/输出 API(NIO.2).但是对于 ...

随机推荐

  1. 《Entity Framework 6 Recipes》中文翻译系列 (45) ------ 第八章 POCO之获取原始对象与手工同步对象图和变化跟踪器

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-6  获取原始对象 问题 你正在使用POCO,想从数据库获取原始对象. 解决方案 ...

  2. Service基础使用

    Service基础使用 之前的文章一直介绍Activity的使用,很多知识和用法单一的配合Activity使用,这次将总结Android四大组件之二--Service. 本文将要介绍以下内容: Ser ...

  3. The replication agent has not logged a progress message in 10 minutes.

    打开Replication Monitor,在Subscription Watch List Tab中,发现有大量的status= “Performance critical” 的黄色Warning, ...

  4. LINQ系列:Linq to Object分组操作符

    分组是指根据一个特定的值将序列中的值或元素进行分组.LINQ只包含一个分组操作符:GroupBy. GroupBy 1>. 原型定义 public static IQueryable<IG ...

  5. 【Win10 开发】读取PDF文档

    关于用来读取PDF文档的内容的API,其实在Win8.1的时候就有,不过没关系,既咱们讨论的是10的UAP,连同8.1的内容也包括进去,所以老周无数次强调:把以前的内容学好了,就可以在不学习任何新知识 ...

  6. jquery 拖拽,框选的一点积累

    拖拽draggable,框选 selectable,按ctrl多选,临近辅助对齐,从工具栏拖工具  等,和jqueryui的selectable不同,是在一个父div里框选子div(类似框选文件),一 ...

  7. JavaScript 中的类方法,对象方法,Prototype方法

    <script type="text/javascript"> function baseClass() { this.showMsg = function() { a ...

  8. lintcode循环数组之连续子数组求和

    v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. ...

  9. DOM操作

    DOM操作,JS来操作页面 wiindows对象操作 document对象操作 点击事件:将DIV要执行的事件代码装封 onclick  鼠标单击       ondblelick  鼠标双击 onk ...

  10. EntityFramework之你不知道的那些事(七)

    前言 前面一系列几乎都是循序渐进式的进行叙述,似乎脚步走得太快了,于是我开始歇一歇去追寻一些我所不太了解的细枝末节,在此过程中也屡次碰壁,但是唯有如此才能更好的成长,不是吗!希望此文对你亦有帮助. 属 ...