簡單的java io測試

          作者:tacy.lee

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

          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();
                  }
              }
          }
          

           

          測試結果:

          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

           

          來看看他們都怎么執行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每次讀取文件長度512字節,每次寫入文件長度不定,文件讀取操作非常頻繁。

           
          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
          
          
          每次讀取文件長度8k,每次寫入文件長度不定,文件操作已經大大減少。

           

          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,對于IO的壓力應該算比較小了。

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

          del.icio.us Tags: ,

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

          評論

          # re: 簡單的java io測試[未登錄] 2007-09-20 14:53 javacap

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

          # re: 簡單的java io測試 2007-09-20 15:00 tacy lee

          呵呵 用zipfile應該能更快一點  回復  更多評論   

          # re: 簡單的java io測試 2007-09-20 16:20 千里冰封

          呵呵,樓主可以把代碼放到代碼框里,這樣更好看一些  回復  更多評論   

          # re: 簡單的java io測試[未登錄] 2007-09-20 18:09 tacy lee

          ;) 修改了一下排版,加了ZipFile方法,簡單測試了一下,和extractnio差不多  回復  更多評論   

          主站蜘蛛池模板: 安新县| 盘锦市| 长兴县| 永清县| 灵宝市| 长宁县| 邢台县| 绥德县| 正镶白旗| 梁山县| 菏泽市| 嘉兴市| 卢湾区| 克什克腾旗| 桐庐县| 土默特左旗| 礼泉县| 莒南县| 柯坪县| 沅陵县| 元氏县| 靖江市| 西充县| 革吉县| 沧源| 湘西| 昔阳县| 紫云| 宁晋县| 景德镇市| 福泉市| 邛崃市| 平塘县| 赤壁市| 阳山县| 浙江省| 高阳县| 波密县| 宁津县| 关岭| 什邡市|