簡(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可以試試
posted on 2007-09-20 14:27 tacy lee 閱讀(1565) 評(píng)論(4) 編輯 收藏 所屬分類: 性能相關(guān)