在软件系统中,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. MySQL服务无法启动(1067)问题

    关于这个问题网上的帖子和说法多如牛毛,是在难以分辨真假,或者是否与自己的出错情况相同. 有了前车之鉴,就有必要提前声明,这篇是我在计算机--管理--服务中启动mysql服务时出现的错误,如下: 最后的 ...

  2. Posting array of JSON objects to MVC3 action method via jQuery ajax

    Does the model binder not suport arrays of JSON objects? The code below works when sending a single ...

  3. leetcode 659. Split Array into Consecutive Subsequences

    You are given an integer array sorted in ascending order (may contain duplicates), you need to split ...

  4. YTU 2435: C++ 习题 输出日期时间--友元函数

    2435: C++ 习题 输出日期时间--友元函数 时间限制: 1 Sec  内存限制: 128 MB 提交: 1069  解决: 787 题目描述 设计一个日期类和时间类,编写display函数用于 ...

  5. HDU - 2586 How far away ?(离线Tarjan算法)

    1.给定一棵树,每条边都有一定的权值,q次询问,每次询问某两点间的距离. 2.这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了. 这里的计算方法是,记下根结点到任意一 ...

  6. android编程取消标题栏方法(appcompat_v7、Theme.NoTitleBar)

    方式一:编码方式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...

  7. 创建cell的三种方式

    方式一 注册cell -> 无需为cell绑定标识符 [使用UIViewController完成!] l  1> static NSString * const ID = @"c ...

  8. bzoj4289 PA2012 Tax——点边转化

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 好巧妙的转化!感觉自己难以想出来... 参考了博客:https://blog.csdn ...

  9. 关于使用jxl去读写Excel文件

    1.引入maven依赖 <dependency> <groupId>net.sourceforge.jexcelapi</groupId> <artifact ...

  10. 【转载】Nginx 的工作原理 和优化

    1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(locati ...