在软件系统中,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. 2016/05/15 ThinkPHP3.2.2 表单自动验证实例 验证规则的数组 直接写在相应的控制器里

    使用TP 3.2框架 验证规则也可以写到模型里,但感觉有些麻烦, 一是有时候不同页面验证的方式会不一样, 二是看到这个   Add  事件里的代码,就清楚要接收什么数据,如何验证数据能够在第一眼有个大 ...

  2. Hibernate 之 二级缓存

    在上篇文章中我们对缓存以及Hibernate的一级缓存进行了介绍,接下来的主要内容将是Hibernate的二级缓存. 二级缓存也称为进程级的缓存或SessionFactory级的缓存,二级缓存可以被所 ...

  3. 问题:IIS部署 MVC项目 (autofac) 错误解决

    http://www.cnblogs.com/yelaiju/p/3375168.html Could not load file or assembly 'System.Core, Version= ...

  4. chrome浏览器世界之窗浏览器的收藏夹在哪?

    今天心血来潮,用一个查重软件删除重复文件,结果把chrome浏览器和世界之窗浏览器的收藏夹给删除了,导致我保存的好多网页都没有了,在浏览器本身和网上都没有找到这两个浏览器默认的收藏夹在哪个位置,只好用 ...

  5. docker registry的CI规划

    目前代码全部署在docker中, 考虑用jenkins打包成docker包再推送到docker registry 打包推送过程中自动按照日期打标签,并且刷新latest

  6. 吃CPU的openmp 程序

    g++ -o eat -fopenmp eat.cpp #include "stdio.h" int main(int argc, char *argv[]) { #pragma ...

  7. lucene DocValues——本质是为通过docID查找某field的值 看图

    Why DocValues? The standard way that Solr builds the index is with an inverted index. This style bui ...

  8. 前端之html第一天

    一.内容

  9. less 语法

    1 变量 less的变量使用@开头 1.1 demo @colorRed:red; @colorBlue:blue; .demo{ color:@colorRed; background-color: ...

  10. 解决Linux主机上的 远程MySQL客户端无法连接的问题

    无法连接到 MySQL 数据库可能的原因有: 1. PHP 无法连接 MySQL 可能是 PHP 配置不正确,没加上连接 MySQL 的功能. 2. MySQL 软件包升级,但没有升级数据库,或安装 ...