Java實現檔案拷貝的4種方法.
使用 java 進行檔案拷貝 相信很多人都會用,,不過效率上是否最好呢?
最近看了看NIO決定試一試 java NIO 到底有什麼效能的提升.
第一種方法:古老的方式
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
byte[] buffer=new byte[length];
while(true){
int ins=in.read(buffer);
if(ins==-1){
in.close();
out.flush();
out.close();
return new Date().getTime()-time;
}else
out.write(buffer,0,ins);
}
}
方法的2引數分別是原始檔案,和拷貝的目的檔案.這裡不做過多介紹.
實現方法很簡單,分別對2個檔案構建輸入輸出流,並且使用一個位元組陣列作為我們記憶體的快取器, 然後使用流從f1 中讀出資料到快取裡,在將快取資料寫到f2裡面去.這裡的快取是2MB的位元組陣列
第2種方法:使用NIO中的管道到管道傳輸
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
FileChannel inC=in.getChannel();
FileChannel outC=out.getChannel();
int i=0;
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<20971520)
length=(int)(inC.size()-inC.position());
else
length=20971520;
inC.transferTo(inC.position(),length,outC);
inC.position(inC.position()+length);
i++;
}
}
實現方法:在第一種實現方法基礎上對輸入輸出流獲得其管道,然後分批次的從f1的管道中像f2的管道中輸入資料每次輸入的資料最大為2MB
方法3:記憶體檔案景象寫(讀檔案沒有使用檔案景象,有興趣的可以回去試試,,我就不試了,估計會更快)
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
RandomAccessFile out=new RandomAccessFile(f2,"rw");
FileChannel inC=in.getChannel();
MappedByteBuffer outC=null;
MappedByteBuffer inbuffer=null;
byte[] b=new byte[length];
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.force();
out.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<length){
length=(int)(inC.size()-inC.position());
}else{
length=20971520;
}
b=new byte[length];
inbuffer=inC.map(MapMode.READ_ONLY,inC.position(),length);
inbuffer.load();
inbuffer.get(b);
outC=out.getChannel().map(MapMode.READ_WRITE,inC.position(),length);
inC.position(b.length+inC.position());
outC.put(b);
outC.force();
}
}
實現方法:跟傷2個例子不一樣,這裡寫檔案流沒有使用管道而是使用記憶體檔案對映(假設檔案f2在記憶體中).在迴圈中從f1的管道中讀取資料到位元組陣列裡,然後在像記憶體對映的f2檔案中寫資料.
第4種方法:管道對管道
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
FileChannel inC=in.getChannel();
FileChannel outC=out.getChannel();
ByteBuffer b=null;
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<length){
length=(int)(inC.size()-inC.position());
}else
length=2097152;
b=ByteBuffer.allocateDirect(length);
inC.read(b);
b.flip();
outC.write(b);
outC.force(false);
}
}
這裡實現方式與第3種實現方式很類似,不過沒有使用記憶體影射.
下面是對49.3MB的檔案進行拷貝的測試時間(毫秒)
Start Copy File... file size:50290KB
CopyFile:b1.rmvb mode:forChannel RunTime:3203
CopyFile:b1.rmvb mode:forImage RunTime:3328
CopyFile:b1.rmvb mode:forJava RunTime:2172
CopyFile:b1.rmvb mode:forTransfer RunTime:1406
End Copy File!
解釋: 在測試結果中看到 古老方式,和管道向管道傳輸是最快的,,,,,為什麼呢?
我分析是這樣的,由於另外2種方法內部都使用了 位元組陣列作為快取中轉,在加上NIO內部有一個貼近系統的快取區,這無意就增加了另一個快取器,所以相對於這2個方法就要慢許多,,如果不使用 位元組陣列作為資料中轉的話相信速度會更快的..
不過比較驚訝的是 管道向管道傳輸的速度還是真挺嚇人,,,
我的機器是 IDE硬碟120G 硬碟快取2MB, 記憶體1GB, CPU AMD2800+
相關文章
- 【JS】深拷貝與淺拷貝,實現深拷貝的幾種方法JS
- JS中的深淺拷貝以及實現深拷貝的幾種方法.JS
- Java-0024-用I/O實現拷貝檔案Java
- JavaScript實現淺拷貝的方法JavaScript
- [java IO流]之檔案拷貝Java
- 淺談深拷貝與淺拷貝?深拷貝幾種方法。
- 淺拷貝與深拷貝的實現
- C語言實現字串拷貝函式的幾種方法C語言字串函式
- IOCP 檔案拷貝
- 實現物件淺拷貝、深拷貝物件
- 深拷貝與淺拷貝的實現(一)
- Linux使用expect實現遠端拷貝檔案Linux
- JavaScript深拷貝的幾種方法JavaScript
- java陣列拷貝的方法Java陣列
- 【ASM學習】從ASM拷貝檔案的方法ASM
- 自己寫的unix檔案拷貝指令cp實現函式函式
- js 深拷貝兩種方法JS
- js實現深拷貝和淺拷貝JS
- Java IO 流之拷貝(複製)檔案Java
- IO流-檔案拷貝
- 檔案內容拷貝
- xcopy 實現批處理拷貝檔案或資料夾
- Golang命令列拷貝檔案Golang命令列
- Java深拷貝和淺拷貝Java
- 跨網路拷貝檔案的簡單實踐
- 深拷貝和淺拷貝的區別是什麼?實現一個深拷貝
- asm拷貝檔案到檔案系統ASM
- [JS系列二]談談深拷貝和淺拷貝,如何實現深拷貝JS
- js實現深拷貝JS
- 【進階4-4期】Lodash是如何實現深拷貝的
- 一文搞懂Java引用拷貝、淺拷貝、深拷貝Java
- c語言拷貝檔案程式C語言
- Python基礎 - 檔案拷貝Python
- 二進位制檔案拷貝
- 安卓/Java物件拷貝(淺/深拷貝、兩種序列化、Beans等工具)安卓Java物件Bean
- 淺談Java中的淺拷貝和深拷貝Java
- Python中4種方法實現 xls 檔案轉 xlsxPython
- 怎麼實現深拷貝