利用IO流中的隨機訪問文件 RandomAccessFile 和文件通道 FileChanne 復制文件可大大提高文件的讀寫效率,在此基礎上利用多線程復制文件使其性能更優。因線程的個數可根據文件的大小及需求而定。其大概原理是根據給定的線程個數,將文件分段,每個線程負責的數據大小=文件長度/線程個數,將不能除盡的部分留給最后一段文件所分配的線程處理。以下是實現代碼及自己理解的注釋,多有偏差請見諒。下面是兄弟連java培訓
總結的一些代碼:供參考。
程序實現類代碼:
importjava.io.RandomAccessFile;
importjava.nio.channels.FileChannel;
importjava.nio.channels.FileLock;
//定義一個CopyThread類繼承Thread類
public class CopyThreadextends Thread{
private String srcPath;//原文件地址
private String destPath;//目標文件地址
private int start,end;//start指定起始位置,end指定結束位置
//構造CopyThread方法
public CopyThread(StringsrcPath, String destPath, int start, int end) {
this.srcPath = srcPath;//要復制的源文件路徑
this.destPath = destPath;//復制到的文件路徑
this.start = start;//復制起始位置
this.end = end;//復制結束位置
}
//重寫run()方法
public void run() {
try {
//創建一個只讀的隨機訪問文件
RandomAccessFile in = newRandomAccessFile(srcPath, "r");
//創建一個可讀可寫的隨機訪問文件
RandomAccessFile out = newRandomAccessFile(destPath, "rw");
in.seek(start);// 將輸入跳轉到指定位置
out.seek(start);// 從指定位置開始寫
FileChannel inChannel =in.getChannel(); //文件輸入通道
FileChannel outChannel =out.getChannel();//文件輸出通道
//鎖住需要操作的區域,false代表鎖住
FileLock lock = outChannel.lock(start,(end-start), false);
//將字節從此通道的文件傳輸到給定的可寫入字節的outChannel通道。
inChannel.transferTo(start,(end-start), outChannel);
lock.release();//釋放鎖
out.close();//從里到外關閉文件
in.close();//關閉文件
} catch (Exception e) {
e.printStackTrace();
}
}
}
測試類代碼:
import java.io.File;
public class TestMain {
public static voidmain(String[] args) {
//要復制的源文件路徑
String srcPath ="F:\\sun\\上課筆記\\aa.txt";
String destPath ="F:\\sun\\上課筆記\\aa復件.txt";
// 獲得源文件長度
File f = new File(srcPath);
long len = f.length();
int count = 3;// 需要的線程數
int oneNum = (int) (len /count);//每個線程負責的文件長度,強制轉換成int類型
//用for循環處理划分文件的第一部分跟第二部分(循環次數可根據定義的線程數調整)
for (int i = 0; i <count - 1; i++) {
//oneNum * i 起始位置, oneNum * (i + 1)要復制數據的長度
CopyThread ct = newCopyThread(srcPath, destPath, oneNum * i,oneNum * (i + 1));
ct.start();
}
//文件長度不能整除的部分放到最后一段處理
CopyThread ct = newCopyThread(srcPath, destPath, oneNum * (count-1),(int)len);
ct.start();
}
}