使用 java 進(jìn)行文件拷貝 相信很多人都會(huì)用,,不過(guò)效率上是否最好呢?

澠池ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
java NIO 性能提升.
第一種方法:古老的方式
Java代碼
public static long forJava(File f1,File f2) throws Exception{
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);
}
}
public static long forJava(File f1,File f2) throws Exception{
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參數(shù)分別是原始文件,和拷貝的目的文件.這里不做過(guò)多介紹.
實(shí)現(xiàn)方法很簡(jiǎn)單,分別對(duì)2個(gè)文件構(gòu)建輸入輸出流,并且使用一個(gè)字節(jié)數(shù)組作為我們內(nèi)存的緩存器, 然后使用流從f1 中讀出數(shù)據(jù)到緩存里,在將緩存數(shù)據(jù)寫到f2里面去.這里的緩存是2MB的字節(jié)數(shù)組
第2種方法:使用NIO中的管道到管道傳輸
Java代碼
public static long forTransfer(File f1,File f2) throws Exception{
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++;
}
}
public static long forTransfer(File f1,File f2) throws Exception{
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++;
}
}
實(shí)現(xiàn)方法:在第一種實(shí)現(xiàn)方法基礎(chǔ)上對(duì)輸入輸出流獲得其管道,然后分批次的從f1的管道中像f2的管道中輸入數(shù)據(jù)每次輸入的數(shù)據(jù)最大為2MB
方法3:內(nèi)存文件景象寫(讀文件沒(méi)有使用文件景象,有興趣的可以回去試試,,我就不試了,估計(jì)會(huì)更快)
Java代碼
public static long forImage(File f1,File f2) throws Exception{
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();
}
}
public static long forImage(File f1,File f2) throws Exception{
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();
}
}
實(shí)現(xiàn)方法:跟傷2個(gè)例子不一樣,這里寫文件流沒(méi)有使用管道而是使用內(nèi)存文件映射(假設(shè)文件f2在內(nèi)存中).在循環(huán)中從f1的管道中讀取數(shù)據(jù)到字節(jié)數(shù)組里,然后在像內(nèi)存映射的f2文件中寫數(shù)據(jù).
第4種方法:管道對(duì)管道
Java代碼
public static long forChannel(File f1,File f2) throws Exception{
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);
}
}
注:參數(shù)中的File可以這樣定義:
FIle f1 = new File("C:\\test.dat");
File f2 = new File("D:\\test.dat");
界面上使用這個(gè)虛擬路徑,就可以輸出這個(gè)圖片或者文件路徑的。
文件從本地到服務(wù)器的功能,其實(shí)是為了解決目前瀏覽器不支持獲取本地文件全路徑。不得已而想到上傳到服務(wù)器的固定目錄,從而方便項(xiàng)目獲取文件,進(jìn)而使程序支持EXCEL批量導(dǎo)入數(shù)據(jù)。
java中文件上傳到服務(wù)器的指定路徑的代碼:
在前臺(tái)界面中輸入:
form method="post" enctype="multipart/form-data" ?action="../manage/excelImport.do"
請(qǐng)選文件:input type="file" ?name="excelFile"
input type="submit" value="導(dǎo)入" onclick="return impExcel();"/
/form
action中獲取前臺(tái)傳來(lái)數(shù)據(jù)并保存
/**
* excel 導(dǎo)入文件
* @return
* @throws IOException
*/
@RequestMapping("/usermanager/excelImport.do")
public String excelImport(
String filePath,
MultipartFile ?excelFile,HttpServletRequest request) throws IOException{
log.info("action:{} Method:{} start","usermanager","excelImport" );
if (excelFile != null){
String filename=excelFile.getOriginalFilename();
String a=request.getRealPath("u/cms/www/201509");
SaveFileFromInputStream(excelFile.getInputStream(),request.getRealPath("u/cms/www/201509"),filename);//保存到服務(wù)器的路徑
}
log.info("action:{} Method:{} end","usermanager","excelImport" );
return "";
}
/**
* 將MultipartFile轉(zhuǎn)化為file并保存到服務(wù)器上的某地
*/
public void SaveFileFromInputStream(InputStream stream,String path,String savefile) throws IOException
{ ? ?
FileOutputStream fs=new FileOutputStream( path + "/"+ savefile);
System.out.println("------------"+path + "/"+ savefile);
byte[] buffer =new byte[1024*1024];
int bytesum = 0;
int byteread = 0;
while ((byteread=stream.read(buffer))!=-1)
{
bytesum+=byteread;
fs.write(buffer,0,byteread);
fs.flush();
}
fs.close();
stream.close();
}
下面列舉出4種方式:
1、使用FileStreams復(fù)制
這是最經(jīng)典的方式將一個(gè)文件的內(nèi)容復(fù)制到另一個(gè)文件中。 使用FileInputStream讀取文件A的字節(jié),使用FileOutputStream寫入到文件B。正如你所看到的我們執(zhí)行幾個(gè)讀和寫操作try的數(shù)據(jù),所以這應(yīng)該是一個(gè)低效率的,下一個(gè)方法我們將看到新的方式。 這是第一個(gè)方法的代碼:
2、使用FileChannel復(fù)制
Java NIO包括transferFrom方法,根據(jù)文檔應(yīng)該比文件流復(fù)制的速度更快。 這是第二種方法的代碼:
3、使用Commons IO復(fù)制
Apache Commons IO提供拷貝文件方法在其FileUtils類,可用于復(fù)制一個(gè)文件到另一個(gè)地方。它非常方便使用Apache Commons FileUtils類時(shí),您已經(jīng)使用您的項(xiàng)目。基本上,這個(gè)類使用Java NIO FileChannel內(nèi)部。 這是第三種方法的代碼:
4、使用Java7的Files類復(fù)制
如果你有一些經(jīng)驗(yàn)在Java 7中你可能會(huì)知道,可以使用復(fù)制方法的Files類文件,從一個(gè)文件復(fù)制到另一個(gè)文件。 這是第四個(gè)方法的代碼:
本文標(biāo)題:java傳目錄代碼 java目錄存放java源代碼
瀏覽路徑:http://chinadenli.net/article34/ddocgpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、用戶體驗(yàn)、搜索引擎優(yōu)化、企業(yè)網(wǎng)站制作、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)