最近學習netty的時候發現nio包下有個FileChannel類,經過了解這個類作用是個專門負責傳輸檔案的通道,支持多執行緒,而且經過反復多次測驗FileChannel復制檔案的速度比BufferedInputStream/BufferedOutputStream復制檔案的速度快了近三分之一,在復制大檔案的時候更加體現出FileChannel的速度優勢,而且FileChannel是多并發執行緒安全的,代碼也比較簡潔
代碼貼下
package com.niu.nio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
/**
* @description:
* @author: nxq email: niuxiangqian163@163.com
* @createDate: 2020/12/28 5:48 下午
* @updateUser: nxq email: niuxiangqian163@163.com
* @updateDate: 2020/12/28 5:48 下午
* @updateRemark:
* @version: 1.0
**/
public class Main {
public static void main(String[] args) {
quickCopy(new File("/Users/laoniu/a.txt"),new File("/Users/laoniu/b.txt"));
}
/**
* 快速copy
* @author nxq
* @param src: 源檔案
* @param target: 目標檔案
* @return void
*/
public static void quickCopy(File src, File target){
try(FileInputStream inputStream = new FileInputStream(src);
FileOutputStream outputStream = new FileOutputStream(target);
FileChannel inputChannel = inputStream.getChannel(); // 得到源檔案通道
FileChannel outputChannel = outputStream.getChannel()// 得到目標檔案通道
) {
//將源檔案資料通達連通到目標檔案通道進行傳輸
inputChannel.transferTo(0,inputChannel.size(),outputChannel);
}catch (Exception e){
e.printStackTrace();
}
}
}
關于這種io流關閉方式不清楚的同學請看我這篇文章:https://laoniu.blog.csdn.net/article/details/111896446
測驗對比
復制目標檔案:
![]()
4.76GB
代碼
package com.niu.nio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
/**
* @description:
* @author: nxq email: niuxiangqian163@163.com
* @createDate: 2020/12/28 5:48 下午
* @updateUser: nxq email: niuxiangqian163@163.com
* @updateDate: 2020/12/28 5:48 下午
* @updateRemark:
* @version: 1.0
**/
public class Main {
public static void main(String[] args) {
long start = System.currentTimeMillis();
File src = new File("/Users/laoniu/Downloads/installer/cn_windows_10_business_edition_version_1809_updated_sept_2018_x64_dvd_fc5542c0.iso"); //檔案4.76GB
quickCopy(src,new File("/Users/laoniu/test/a.iso"));
long end = System.currentTimeMillis();
System.out.println("FileChannel復制:"+(end - start));
start = System.currentTimeMillis();
copy(src,new File("/Users/laoniu/test/b.iso"));
end = System.currentTimeMillis();
System.out.println("普通復制:"+(end - start));
}
/**
* 快速copy
* @author nxq
* @param src: 源檔案
* @param target: 目標檔案
* @return void
*/
public static void quickCopy(File src, File target){
try(FileInputStream inputStream = new FileInputStream(src);
FileOutputStream outputStream = new FileOutputStream(target);
FileChannel inputChannel = inputStream.getChannel(); // 得到源檔案檔案通道
FileChannel outputChannel = outputStream.getChannel()// 得到目標檔案通道
) {
//將源檔案資料通達連通到目標檔案通道進行傳輸
inputChannel.transferTo(0,inputChannel.size(),outputChannel);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 普通copy
* @author nxq
* @param src:
* @param target:
* @return void
*/
public static void copy(File src, File target){
try(FileInputStream inputStream = new FileInputStream(src);
FileOutputStream outputStream = new FileOutputStream(target);
) {
byte[] data = new byte[1024*1024]; //加大每次讀取的資料多少
int len;
while ((len = inputStream.read(data))!=-1){
outputStream.write(data,0,len);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
加大每次讀取的資料到1024*1024,否則更慢
結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/242866.html
標籤:java
下一篇:idea搭建ssm框架
