在软件系统中,IO速度比内存速度慢,IO读写在很多情况下会是系统的瓶颈。

在java标准IO操作中,InputStream和OutputStream提供基于流的IO操作,以字节为处理单位;Reader和Writer实现了Buffered缓存,以字符为处理单位。

从Java1.4开始,增加NIO(New IO),增加缓存Buffer和通道Channel,以块为处理单位,是双向通道(可读可写,类似RandomAccessFile),支持锁和内存映射文件访问接口,大大提升了IO速度。

以下例子简单测试常见IO操作的性能速度。

  1. /**
  2. * 测试不同io操作速度
  3. *
  4. * @author peter_wang
  5. * @create-time 2014-6-4 下午12:52:48
  6. */
  7. public class SpeedTest {
  8. private static final String INPUT_FILE_PATH = "io_speed.txt";
  9. private static final String OUTPUT_FILE_PATH = "io_speed_copy.txt";
  10. /**
  11. * @param args
  12. */
  13. public static void main(String[] args) {
  14. long ioStreamTime1 = ioStreamCopy();
  15. System.out.println("io stream copy:" + ioStreamTime1);
  16. long ioStreamTime2 = bufferedStreamCopy();
  17. System.out.println("buffered stream copy:" + ioStreamTime2);
  18. long ioStreamTime3 = nioStreamCopy();
  19. System.out.println("nio stream copy:" + ioStreamTime3);
  20. long ioStreamTime4 = nioMemoryStreamCopy();
  21. System.out.println("nio memory stream copy:" + ioStreamTime4);
  22. }
  23. /**
  24. * 普通文件流读写
  25. *
  26. * @return 操作的时间
  27. */
  28. private static long ioStreamCopy() {
  29. long costTime = -1;
  30. FileInputStream is = null;
  31. FileOutputStream os = null;
  32. try {
  33. long startTime = System.currentTimeMillis();
  34. is = new FileInputStream(INPUT_FILE_PATH);
  35. os = new FileOutputStream(OUTPUT_FILE_PATH);
  36. int read = is.read();
  37. while (read != -1) {
  38. os.write(read);
  39. read = is.read();
  40. }
  41. long endTime = System.currentTimeMillis();
  42. costTime = endTime - startTime;
  43. }
  44. catch (FileNotFoundException e) {
  45. e.printStackTrace();
  46. }
  47. catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. finally {
  51. try {
  52. if (is != null) {
  53. is.close();
  54. }
  55. if (os != null) {
  56. os.close();
  57. }
  58. }
  59. catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. return costTime;
  64. }
  65. /**
  66. * 加入缓存的文件流读写, Reader默认实现缓存,只能读取字符文件,无法准确读取字节文件如图片视频等
  67. *
  68. * @return 操作的时间
  69. */
  70. private static long bufferedStreamCopy() {
  71. long costTime = -1;
  72. FileReader reader = null;
  73. FileWriter writer = null;
  74. try {
  75. long startTime = System.currentTimeMillis();
  76. reader = new FileReader(INPUT_FILE_PATH);
  77. writer = new FileWriter(OUTPUT_FILE_PATH);
  78. int read = -1;
  79. while ((read = reader.read()) != -1) {
  80. writer.write(read);
  81. }
  82. writer.flush();
  83. long endTime = System.currentTimeMillis();
  84. costTime = endTime - startTime;
  85. }
  86. catch (FileNotFoundException e) {
  87. e.printStackTrace();
  88. }
  89. catch (IOException e) {
  90. e.printStackTrace();
  91. }
  92. finally {
  93. try {
  94. if (reader != null) {
  95. reader.close();
  96. }
  97. if (writer != null) {
  98. writer.close();
  99. }
  100. }
  101. catch (IOException e) {
  102. e.printStackTrace();
  103. }
  104. }
  105. return costTime;
  106. }
  107. /**
  108. * nio操作数据流
  109. *
  110. * @return 操作的时间
  111. */
  112. private static long nioStreamCopy() {
  113. long costTime = -1;
  114. FileInputStream is = null;
  115. FileOutputStream os = null;
  116. FileChannel fi = null;
  117. FileChannel fo = null;
  118. try {
  119. long startTime = System.currentTimeMillis();
  120. is = new FileInputStream(INPUT_FILE_PATH);
  121. os = new FileOutputStream(OUTPUT_FILE_PATH);
  122. fi = is.getChannel();
  123. fo = os.getChannel();
  124. ByteBuffer buffer = ByteBuffer.allocate(1024);
  125. while (true) {
  126. buffer.clear();
  127. int read = fi.read(buffer);
  128. if (read == -1) {
  129. break;
  130. }
  131. buffer.flip();
  132. fo.write(buffer);
  133. }
  134. long endTime = System.currentTimeMillis();
  135. costTime = endTime - startTime;
  136. }
  137. catch (FileNotFoundException e) {
  138. e.printStackTrace();
  139. }
  140. catch (IOException e) {
  141. e.printStackTrace();
  142. }
  143. finally {
  144. try {
  145. if (fi != null) {
  146. fi.close();
  147. }
  148. if (fo != null) {
  149. fo.close();
  150. }
  151. if (is != null) {
  152. is.close();
  153. }
  154. if (os != null) {
  155. os.close();
  156. }
  157. }
  158. catch (IOException e) {
  159. e.printStackTrace();
  160. }
  161. }
  162. return costTime;
  163. }
  164. /**
  165. * nio内存映射操作数据流
  166. *
  167. * @return 操作的时间
  168. */
  169. private static long nioMemoryStreamCopy() {
  170. long costTime = -1;
  171. FileInputStream is = null;
  172. //映射文件输出必须用RandomAccessFile
  173. RandomAccessFile os = null;
  174. FileChannel fi = null;
  175. FileChannel fo = null;
  176. try {
  177. long startTime = System.currentTimeMillis();
  178. is = new FileInputStream(INPUT_FILE_PATH);
  179. os = new RandomAccessFile(OUTPUT_FILE_PATH, "rw");
  180. fi = is.getChannel();
  181. fo = os.getChannel();
  182. IntBuffer iIb=fi.map(FileChannel.MapMode.READ_ONLY, 0, fi.size()).asIntBuffer();
  183. IntBuffer oIb = fo.map(FileChannel.MapMode.READ_WRITE, 0, fo.size()).asIntBuffer();
  184. while(iIb.hasRemaining()){
  185. int read = iIb.get();
  186. oIb.put(read);
  187. }
  188. long endTime = System.currentTimeMillis();
  189. costTime = endTime - startTime;
  190. }
  191. catch (FileNotFoundException e) {
  192. e.printStackTrace();
  193. }
  194. catch (IOException e) {
  195. e.printStackTrace();
  196. }
  197. finally {
  198. try {
  199. if (fi != null) {
  200. fi.close();
  201. }
  202. if (fo != null) {
  203. fo.close();
  204. }
  205. if (is != null) {
  206. is.close();
  207. }
  208. if (os != null) {
  209. os.close();
  210. }
  211. }
  212. catch (IOException e) {
  213. e.printStackTrace();
  214. }
  215. }
  216. return costTime;
  217. }
  218. }

运行结果:

  1. io stream copy:384
  2. buffered stream copy:125
  3. nio stream copy:12
  4. nio memory stream copy:10

结论分析:

最普通的InputStream操作耗时较长,增加了缓存后速度增加了,用了nio和内存映射访问文件,速度最快。

java-IO操作性能对比的更多相关文章

  1. java IO性能对比----read文件

    本次对比内容为:(jdk1.8) fileInputStream:最基本的文件读取(带自己声明的缓冲区) dataInputStream:字节读取,在<java编程思想>一书中描述为使用最 ...

  2. Java IO编程全解(六)——4种I/O的对比与选型

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面讲到:Java IO编程全解(五)--AIO编程 为了防止由于对一些技术概念和术语 ...

  3. Java NIO 学习笔记(七)----NIO/IO 的对比和总结

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  4. java io读取性能对比

    背景 从最早bio的只支持阻塞的bio(同步阻塞) 到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)(此时加入mmap类) 再到aio(异步非阻塞) 虽然这些api改变了调用模式,但真正执行效率上是 ...

  5. Java中的NIO和IO的对比分析

    总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...

  6. Java IO流之【缓冲流和文件流复制文件对比】

    与文件流相比,缓冲流复制文件更快 代码: package Homework; import java.io.BufferedOutputStream; import java.io.File; imp ...

  7. JAVA IO 序列化与设计模式

    ➠更多技术干货请戳:听云博客 序列化 什么是序列化 序列化:保存对象的状态 反序列化:读取保存对象的状态 序列化和序列化是Java提供的一种保存恢复对象状态的机制 序列化有什么用 将数据保存到文件或数 ...

  8. Java IO面试

    1. 讲讲IO里面的常见类,字节流.字符流.接口.实现类.方法阻塞. 字节流和字符流的区别: 1)字节流处理单元为1个字节,操作字节和字节数组,而字符流处理的单元为2个字节的Unicode字符,分别操 ...

  9. 关于SpringMVC项目报错:java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/xxxx.xml]

    关于SpringMVC项目报错:java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/xxxx ...

  10. Java IO编程全解(五)——AIO编程

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7794151.html 前面讲到:Java IO编程全解(四)--NIO编程 NIO2.0引入了新的异步通道的 ...

随机推荐

  1. 20170212-备份ABAP程序

    把生产机上所有后续开发的CBO程序都备份下来.以备急用! 用过2种方法:1.写BDC程序,模拟 TCODE:SE38 -->Program --> Utilities(M)-->Mo ...

  2. 使用PXE安装CentOS7

    1.环境 本文使用VMware 虚拟机进行实验. 点击VMware--编辑--虚拟网络编辑器,新建VMnet15,选择仅主机模式,取消勾选DHCP服务(因为这里使用自己的DHCP服务).我这里配好后是 ...

  3. java 泛型的理解与应用

    为什么使用泛型? 举个例子: public class GenericTest { public static void main(String[] args) { List list = new A ...

  4. 协议森林02 小喇叭开始广播 (以太网与WiFi协议)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁任何形式转载. “小喇叭开始广播啦”,如果你知道这个,你一定是老一辈的人.“小喇叭”是五十年代到八十年代的儿童广播 ...

  5. 小程序-demo:小程序示例-page/api

    ylbtech-小程序-demo:小程序示例-page/api 以下将演示小程序接口能力,具体属性参数详见小程序开发文档. 1. page/component返回顶部 1. a) .js Page({ ...

  6. vue demo todo-list

    html <input type='text' v-model="todoItem" v-on:keyup.enter='addItem'> <ul> &l ...

  7. Ubuntu 14.04 配置 Java SE jdk-7u55 (转载)

    转自:http://blog.csdn.net/tecn14/article/details/24797545 JDK  目前最新版为jdk-8u5,这次没有选择安装最新的jdk8,而是要安装jdk7 ...

  8. 如何替换某文件中的所有的特定字符?---linux sed命令(文本编辑命令) (转载)

    转自:http://blog.csdn.net/year_9/article/details/20318407 sed是一个很好的文件处理工具,主要是以行为单位进行处理,可以将数据行进行替换.删除.新 ...

  9. Educational Codeforces Round 14E. Xor-sequences(矩阵快速幂)

    传送门 题意 给定序列,从序列中选择k(1≤k≤1e18)个数(可以重复选择),使得得到的排列满足\(x_i与x_{i+1}\)异或的二进制表示中1的个数是3的倍数.问长度为k的满足条件的序列有多少种 ...

  10. SAS基础 -- SAS编程入门

    SAS语言 -- 简介   SAS语言是一种专用的数据管理与分析语言,它提供了一种完善的编程语言.类似于计算机的高级语言,SAS用户只需要熟悉其命令.语句及简单的语法规则就可以做数据管理和分析处理工作 ...