探索Java NIO的历程

阅读更多

探索Java NIO的历程
前段时间有些时间,打算看看NIO的东西,本来以为很快可以了解的东西,却用了很多时间。
首先Goole NIO可以看到很多的教程,非阻塞,Buffer,内存映射,块读取前三个很快就有所了解
尝试着写了些小程序,学习东西的时候总喜欢写点小例子。
唯独块读取没有找到对应的东西。(在过程中,主要看了IBM 的NIO入门)

首先,IBM NIO入门中的语句
--------------------------------------------------------------------------------
原来的 I/O 库(在 java.io.*中) 与 NIO 最重要的区别是数据打包和传输的方式。正如前面提到的,
原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。 面向流 的 I/O 系统一次一个字节地处
理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。 一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的I/O 所具有的优雅性和简单性。
--------------------------------------------------------------------------------
首先简单的印象是NIO快,所以想写个程序验证一下.如下复制:

 

 1 public   static   void  test2(String name1, String name2)  {
 2          long  start  =  System.currentTimeMillis();
 3          try   {
 4             FileInputStream fis  =   new  FileInputStream(name1);
 5             FileOutputStream fos  =   new  FileOutputStream(name2);
 6              byte [] buf  =   new   byte [ 8129 ];
 7              while  ( true {                
 8                  int  n  =  fis.read(buf);
 9                  if  (n  ==   - 1 {
10                      break ;
11                 }

12                 fos.write(buf, 0 ,n);
13             }

14             fis.close();
15             fos.close();
16         }
  catch  (Exception e)  {
17             e.printStackTrace();
18         }

19          long  end  =  System.currentTimeMillis();
20          long  time  =  end  -  start;
21         System.out.println(time);
22     }

23     
24      public   static   void  test3(String name1, String name2)  {
25          long  start  =  System.currentTimeMillis();
26          try   {
27             FileInputStream in  =   new  FileInputStream(name1);
28             FileOutputStream out  =   new  FileOutputStream(name2);
29             FileChannel fc1  =  in.getChannel();
30             FileChannel fc2  =  out.getChannel();
31             ByteBuffer bb  =  ByteBuffer.allocate( 8129 );
32              while  ( true {
33                 bb.clear();
34                  int  n  =  fc1.read(bb);
35                  if  (n  ==   - 1 {
36                      break ;
37                 }

38                 bb.flip();
39                 fc2.write(bb);
40             }

41             fc1.close();
42             fc2.close();
43         }
  catch  (IOException e)  {
44
45         }

46          long  end  =  System.currentTimeMillis();
47          long  time  =  end  -  start;
48         System.out.println(time);
49     }

本以为可以结束,结果测试结果出乎意料,函数一比函数二要快,就是说Old IO快于NIO ,从此
 也就开始了整个过程:
 为了了解这个问题,仔细搜索并仔细再看IBM 的NIO教程,看到如下这段话
 ---------------------------------------------
 在 JDK 1.4 中原来的 I/O 包和 NIO 已经很好地集成了。 java.io.* 已经以 NIO 为基础重新实现了,
 所以现在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些类包含以块的形式读写数据的方法,
 这使得即使在更面向流的系统中,处理速度也会更快。 也可以用 NIO 库实现标准 I/O 功能。例如,
 可以容易地使用块 I/O 一次一个字节地移动数据。但是正如您会看到的,NIO 还提供了原 I/O 包中所没有的许多好处。
    ---------------------------------------------
    所以我想,是否因为InputStream中使用了块读取实现了呢,所以进入JDK1.4中的InputStream中
    看看source,首先引起我注意的是read函数,当参数是一个byte数组的时候,直接调用的native实现
    难道是这个,为了验证,下载了一个JDK1.3下来,发现JDK1.3是一样的。
   
    继续,我想是否是JVM底层实现了块读取呢,为了证明这个我用JDK1.3和JDK1.4同时实现了类似的函数,    测试的结果再次出乎意料,性能相差不大.那就不是这个了。
  为此多方查找资料,未果,为此多写几个函数,好好测试一下IO的不同。于是有了如下的一些函数

  1 //  exec
  2      public   static   void  test1(String name1, String name2)  {
  3          long  start  =  System.currentTimeMillis();
  4          try   {
  5             String cmd  =   " cmd /c copy d:\\out1.txt d:\\out2.txt " ;
  6             System.out.println(cmd);
  7             Process p  =  Runtime.getRuntime().exec(cmd);÷
  8             p.waitFor();
  9         }
  catch  (Exception e)  {
 10             e.printStackTrace();
 11         }

 12          long  end  =  System.currentTimeMillis();
 13          long  time  =  end  -  start;
 14         System.out.println(time);
 15     }

 16
 17      //  old io
 18      public   static   void  test2(String name1, String name2)  {
 19          long  start  =  System.currentTimeMillis();
 20          try   {
 21             FileInputStream fis  =   new  FileInputStream(name1);
 22             FileOutputStream fos  =   new  FileOutputStream(name2);
 23              while  ( true {
 24                  byte [] buf  =   new   byte [ 8129 ];
 25                  int  n  =  fis.read(buf);
 26                  if  (n  ==   - 1 {
 27                      break ;
 28                 }

 29                 fos.write(buf);
 30             }

 31             fis.close();
 32             fos.close();
 33         }
  catch  (Exception e)  {
 34             e.printStackTrace();
 35         }

 36          long  end  =  System.currentTimeMillis();
 37          long  time  =  end  -  start;
 38         System.out.println(time);
 39     }

 40
 41      //  new io
 42      public   static   void  test3(String name1, String name2)  {
 43          long  start  =  System.currentTimeMillis();
 44          try   {
 45             FileInputStream in  =   new  FileInputStream(name1);
 46             FileOutputStream out  =   new  FileOutputStream(name2);
 47             FileChannel fc1  =  in.getChannel();
 48             FileChannel fc2  =  out.getChannel();
 49             ByteBuffer bb  =  ByteBuffer.allocate( 8129 );
 50              while  ( true {
 51                 bb.clear();
 52                  int  n  =  fc1.read(bb);
 53                  if  (n  ==   - 1 {
 54                      break ;
 55                 }

 56                 bb.flip();
 57                 fc2.write(bb);
 58             }

 59             fc1.close();
 60             fc2.close();
 61         }
  catch  (IOException e)  {
 62

你可能感兴趣的:(Java,IBM,JVM,JDK)