簡(jiǎn)單的java io測(cè)試

          作者:tacy.lee

          寫了一個(gè)解壓縮zip包的方法來測(cè)試,測(cè)試代碼如下:

          import java.io.BufferedInputStream;
          import java.io.BufferedOutputStream;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.nio.channels.Channels;
          import java.nio.channels.FileChannel;
          import java.nio.channels.ReadableByteChannel;
          import java.util.Enumeration;
          import java.util.zip.ZipEntry;
          import java.util.zip.ZipFile;
          import java.util.zip.ZipInputStream;
          
          /**
           * @author tacy.lee@gmail.com
           *
           */
          public class TestNIO {
              
              public static void extract(File zipFile,File destDir) throws Exception{
                  ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
                  ZipEntry zie;
                  
                  while((zie = zis.getNextEntry()) != null){
                      String entryName = zie.getName();
                      File newFile = new File(destDir,entryName);
                      int count;
                      byte[] data = new byte[8192];
                      if(zie.isDirectory()){
                          newFile.mkdirs();
                      }else{
                          BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
                          while((count = zis.read(data)) != -1){
                              bos.write(data,0,count);
                          }
                          bos.flush();
                          bos.close();
                      }
                  }
                  zis.close();
              }
              public static void extractBuf(File zipFile, File destDir) throws Exception { 
                  
                  BufferedInputStream bi = new BufferedInputStream(new FileInputStream(zipFile));
                  ZipInputStream zis = new ZipInputStream(bi);
                  ZipEntry zie; 
                  int BUFFER_SIZE = 8192;
                  
                  while ((zie = zis.getNextEntry()) != null) { 
                      String entryName = zie.getName();
                      // System.out.println("Extracting: " + zipentry.getName());
                      File newFile = new File(destDir , entryName);
                      byte[] data = new byte[BUFFER_SIZE];
                      int count;
                      if (zie.isDirectory()) {
                          newFile.mkdirs();
                      } else { 
                          FileOutputStream fos = new FileOutputStream(newFile);
                          BufferedOutputStream bos = new BufferedOutputStream(fos,BUFFER_SIZE);
                          while((count = zis.read(data,0,BUFFER_SIZE)) != -1){
                              bos.write(data,0,count);
                          }
                          bos.flush();
                          bos.close();
                      }
                  }
                  
                  zis.close();
              }
              
              public static void extractNIOzf(File zipFile,File destDir) throws Exception{
                  ZipFile zf = new ZipFile(zipFile);
                  ZipEntry zie = null;
                  Enumeration et = zf.entries();
                  
                  while(et.hasMoreElements()){
                      zie = (ZipEntry)et.nextElement();
                      File newFile = new File(destDir,zie.getName());
                      ReadableByteChannel rc = Channels.newChannel(zf.getInputStream(zie));
                      if(zie.isDirectory()){
                          newFile.mkdirs();
                      }else{
                          FileOutputStream fos = new FileOutputStream(newFile);
                          FileChannel fc = fos.getChannel();
                          fc.transferFrom(rc, 0, zie.getSize());
                          fos.close();
                      }
                      
                  }
                  zf.close();
              }
              
              public static void extractNIO(File zipFile,File destDir)throws Exception{
                  BufferedInputStream bi = new BufferedInputStream(new FileInputStream(zipFile));
                  ZipInputStream zin = new ZipInputStream(bi);
                  ZipEntry zie;
                  ReadableByteChannel rc = Channels.newChannel(zin);
                  
                  while((zie = zin.getNextEntry()) != null){
                      String entryName = zie.getName();
                      File newFile = new File(destDir,entryName);
                      if(zie.isDirectory()){
                          newFile.mkdirs();
                      }else{
                          FileOutputStream fos = new FileOutputStream(newFile);
                          FileChannel fc = fos.getChannel();
          
                          long count = 0;
                          long size = zie.getSize();
          //                while(count<size){
          //                    long written = fc.transferFrom(rc, count, size);
          //                    count += written;
          //                }
                          fc.transferFrom(rc,0,zie.getSize());
                          fos.close();
                      }
                  }
                  zin.close();
              }
          
              public static void main(String[] args){
                  if (args.length !=3){
                      System.out.println("Usage: TestNIO mode zipFile destDir");
                      System.out.println("mode:");
                      System.out.println("  extract");
                      System.out.println("  extractBuf");
                      System.out.println("  extractNIO");
                      System.out.println("  extractNIOzf");
                      System.exit(1);
                  }
                  File fs = new File(args[1]);
                  File dest = new File(args[2]);
                  try {
                      long avg = 0;
                      for(int i=0;i<10;i++){
                          long st = System.nanoTime();
                          if("extract".equals(args[0].toLowerCase()))
                              extract(fs,dest);
                          if("extractbuf".equals(args[0].toLowerCase()))
                              extractBuf(fs,dest);
                          if("extractnio".equals(args[0].toLowerCase()))
                              extractNIO(fs, dest);
                          if("extractniozf".equals(args[0].toLowerCase()))
                              extractNIOzf(fs,dest);
                          long time = System.nanoTime()-st;
                          System.out.println(time);
                          avg += time;
                      }
                      System.out.println("avg time:" + avg/10);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
          

           

          測(cè)試結(jié)果:

          d:\temp>java TestNIO extract d:\temp\eoshome.zip d:\temp\temp
          5078282016
          12635255040
          10226276244
          13185518830
          11942373961
          17426315635
          15663583500
          12787992329
          12557049290
          11303703403
          avg time:12280635024

          d:\temp>java TestNIO extractbuf d:\temp\eoshome.zip d:\temp\temp
          7431395610
          9422945654
          9896290730
          8881473484
          8312653703
          11012962262
          13153371168
          11235213134
          8617239621
          11440966101
          avg time:9940451146

          d:\temp>java TestNIO extractNIO d:\temp\eoshome.zip d:\temp\temp
          4530841769
          9990226132
          12335196233
          10000922464
          10526305997
          8983492315
          9554596184
          8798381359
          9946382291
          10512609564
          avg time:9517895430

           

          來看看他們都怎么執(zhí)行IO操作的

          1、extract

          29082    13:54:44.3778096    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,462,554, Length: 512
          29083    13:54:44.3778431    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,463,066, Length: 512
          29084    13:54:44.3778741    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,463,578, Length: 512
          29085    13:54:44.3779071    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,464,090, Length: 512
          29086    13:54:44.3779373    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,464,602, Length: 512
          29087    13:54:44.3779674    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,465,114, Length: 512
          29088    13:54:44.3780018    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,465,626, Length: 512
          29089    13:54:44.3780356    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,466,138, Length: 512
          29091    13:54:44.3780660    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,466,650, Length: 512
          29092    13:54:44.3781029    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,467,162, Length: 512
          29093    13:54:44.3781496    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,467,674, Length: 512
          29094    13:54:44.3781800    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,468,186, Length: 512
          29095    13:54:44.3782124    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,468,698, Length: 512
          29096    13:54:44.3782407    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,469,210, Length: 512
          29097    13:54:44.3782694    java.exe    4004    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 2,469,722, Length: 512
          29098    13:54:44.3783060    java.exe    4004    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    FAST IO DISALLOWED    Offset: 1,177,698, Length: 7,753
          29099    13:54:44.3783166    java.exe    4004    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 1,177,698, Length: 7,753
          
          

          ZipInputStream每次讀取文件長(zhǎng)度512字節(jié),每次寫入文件長(zhǎng)度不定,文件讀取操作非常頻繁。

           
          2、extractBuf
          22350    14:03:05.1736921    java.exe    1128    QueryStandardInformationFile    D:\temp\eoshome.zip    SUCCESS    AllocationSize: 38,592,512, EndOfFile: 38,592,090, NumberOfLinks: 1, DeletePending: False, Directory: False
          22351    14:03:05.1737072    java.exe    1128    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 1,359,872, Length: 8,192
          22352    14:03:05.1737740    java.exe    1128    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 31,236, Length: 7,914
          22353    14:03:05.1740799    java.exe    1128    QueryStandardInformationFile    D:\temp\eoshome.zip    SUCCESS    AllocationSize: 38,592,512, EndOfFile: 38,592,090, NumberOfLinks: 1, DeletePending: False, Directory: False
          22354    14:03:05.1740938    java.exe    1128    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 1,368,064, Length: 8,192
          22355    14:03:05.1741394    java.exe    1128    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 39,150, Length: 7,719
          22358    14:03:05.1744629    java.exe    1128    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 46,869, Length: 7,849
          
          
          每次讀取文件長(zhǎng)度8k,每次寫入文件長(zhǎng)度不定,文件操作已經(jīng)大大減少。

           

          3、extractNIO

          23945    14:08:55.0475907    java.exe    480    QueryStandardInformationFile    D:\temp\eoshome.zip    SUCCESS    AllocationSize: 38,592,512, EndOfFile: 38,592,090, NumberOfLinks: 1, DeletePending: False, Directory: False
          23946    14:08:55.0476046    java.exe    480    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 1,335,296, Length: 8,192
          23947    14:08:55.0477401    java.exe    480    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    FAST IO DISALLOWED    Offset: 8,192, Length: 8,192
          23948    14:08:55.0477516    java.exe    480    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 8,192, Length: 8,192
          23949    14:08:55.0480365    java.exe    480    QueryStandardInformationFile    D:\temp\eoshome.zip    SUCCESS    AllocationSize: 38,592,512, EndOfFile: 38,592,090, NumberOfLinks: 1, DeletePending: False, Directory: False
          23950    14:08:55.0480505    java.exe    480    ReadFile    D:\temp\eoshome.zip    SUCCESS    Offset: 1,343,488, Length: 8,192
          23951    14:08:55.0481932    java.exe    480    WriteFile    D:\temp\temp\base\lib\3rd\ant.jar    SUCCESS    Offset: 16,384, Length: 8,192
          
          采用NIO channel之后,每次讀寫均為8k,對(duì)于IO的壓力應(yīng)該算比較小了。

          觀察java的IO操作用的是Systeminternals的Process Monitor,有興趣的tx可以試試

          del.icio.us Tags: ,

          posted on 2007-09-20 14:27 tacy lee 閱讀(1565) 評(píng)論(4)  編輯  收藏 所屬分類: 性能相關(guān)

          評(píng)論

          # re: 簡(jiǎn)單的java io測(cè)試[未登錄] 2007-09-20 14:53 javacap

          zis.getNextEntry() do more things than you think.To use zipFile.entries() may get better permanence.  回復(fù)  更多評(píng)論   

          # re: 簡(jiǎn)單的java io測(cè)試 2007-09-20 15:00 tacy lee

          呵呵 用zipfile應(yīng)該能更快一點(diǎn)  回復(fù)  更多評(píng)論   

          # re: 簡(jiǎn)單的java io測(cè)試 2007-09-20 16:20 千里冰封

          呵呵,樓主可以把代碼放到代碼框里,這樣更好看一些  回復(fù)  更多評(píng)論   

          # re: 簡(jiǎn)單的java io測(cè)試[未登錄] 2007-09-20 18:09 tacy lee

          ;) 修改了一下排版,加了ZipFile方法,簡(jiǎn)單測(cè)試了一下,和extractnio差不多  回復(fù)  更多評(píng)論   

          主站蜘蛛池模板: 岑溪市| 平凉市| 扶风县| 永城市| 沾益县| 汉沽区| 太保市| 察哈| 攀枝花市| 丹棱县| 广安市| 茶陵县| 铁岭市| 三都| 永州市| 房山区| 德保县| 河津市| 鹤庆县| 翼城县| 浮梁县| 达孜县| 无极县| 大悟县| 南涧| 翼城县| 苍南县| 田阳县| 扶绥县| 旺苍县| 昭平县| 陆良县| 阆中市| 大新县| 西峡县| 睢宁县| 沙湾县| 宜兰市| 仁怀市| 龙岩市| 武邑县|