Java语言中加速I/O的基本规则学习--Java编程

时间:2015-5-7 19:45:56

  核心提示:加速I/O的基本规则作为这个讨论的开始,这里有几个如何加速I/O的基本规则: 1. 避免访问磁盘 2. 避免访问底层的操作系统 3. 避免方法调用 4. 避免个别的处理字节和字符 很明显这些规则不能在...

加速I/O的基本规则
作为这个讨论的开始,这里有几个如何加速I/O的基本规则:

1.      避免访问磁盘

2.      避免访问底层的操作系统

3.      避免方法调用

4.      避免个别的处理字节和字符

很明显这些规则不能在所有的问题上避免,因为如果能够的话就没有实际的I/O被执行。考虑下面的计算文件中的新行符('\n')的三部分范例。

方法1: read方法

第一个方法简单的使用FileInputStream的read方法:

import java.io.*;

 

public class intro1 {

     public static void main(String args[]) {

         if (args.length != 1) {

              System.err.println("missing filename");

              System.exit(1);

         }

         try {

              FileInputStream fis = new FileInputStream(args[0]);

              int cnt = 0;

              int b;

              while ((b = fis.read()) != -1) {

                   if (b == '\n')

                       cnt++;

              }

              fis.close();

              System.out.println(cnt);

         } catch (IOException e) {

              System.err.println(e);

         }

     }

}然而这个方法触发了大量的底层运行时系统调用--FileInputStream.read--返回文件的下一个字节的本机方法。

方法 2: 使用大缓冲区

第二种方法使用大缓冲区避免了上面的问题:

import java.io.*;

 

public class intro2 {

     public static void main(String args[]) {

         if (args.length != 1) {

              System.err.println("missing filename");

              System.exit(1);

         }

         try {

              FileInputStream fis = new FileInputStream(args[0]);

              BufferedInputStream bis = new BufferedInputStream(fis);

              int cnt = 0;

              int b;

              while ((b = bis.read()) != -1) {

                   if (b == '\n')

                       cnt++;

              }

              bis.close();

              System.out.println(cnt);

         } catch (IOException e) {

              System.err.println(e);

         }

     }

}

BufferedInputStream.read 从输入缓冲区获取下一个字节,仅仅只访问了一次底层系统。

Java免费学习   Java自学网 http://www.javalearns.com

 

方法 3: 直接缓冲

第三种方法避免使用 BufferedInputStream 而直接缓冲,因此排除了 read 方法的调用:

import java.io.*;

 

public class intro3 {

     public static void main(String args[]) {

         if (args.length != 1) {

              System.err.println("missing filename");

              System.exit(1);

         }

         try {

              FileInputStream fis = new FileInputStream(args[0]);

              byte buf[] = new byte[2048];

              int cnt = 0;

              int n;

              while ((n = fis.read(buf)) != -1) {

                   for (int i = 0; i < n; i++) {

                       if (buf[i] == '\n')

                            cnt++;

                   }

              }

              fis.close();

              System.out.println(cnt);

         } catch (IOException e) {

              System.err.println(e);

         }

     }

}

对于一个1 MB 的输入文件,以秒为单位的执行时间是:

  intro1    6.9 intro2    0.9 intro3    0.4

或者说在最慢的方法和最快的方法间是17比1的不同。

这个巨大的加速并不能证明你应该总是使用第三种方法,即自己做缓冲。这可能是一个错误的倾向特别是在处理文件结束事件时没有仔细的实现。在可读性上它也没有其它方法好。但是记住时间花费在哪儿了以及在必要的时候如何矫正是很有用。

方法2 或许是对于大多应用的 "正确" 方法.

Java免费学习   Java自学网 http://www.javalearns.com

关注微信号:javalearns   随时随地学Java

或扫一扫

随时随地学Java

作者:不详 来源:网络
    你是从哪里知道本网站的?
  • 网友介绍的
  • 百度搜索的
  • Google搜索的
  • 其它搜索过来的
  • 网址输错了进来的
  • 太忙了不记得了
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • java学习网(www.javalearns.com) © 2014 版权所有 All Rights Reserved.
  • Email:javalearns@163.com 站长QQ:1356121699 晋ICP备14003680号-3
  • java学习网部分内容来自网络或网友发布,如侵犯了您利益,请发邮件至:javalearns@126.com,我们尽快处理!
  • Java学习网
  • 网站统计
  • 晋公网安备 14042902000001号