綜合應用題:多執行緒複製檔案(知識點:多執行緒、隨機讀寫流)
阿新 • • 發佈:2019-01-05
要求:使用多執行緒複製一個檔案(使用多執行緒複製一個檔案可以加快檔案的複製速度)
程式碼:
package 多執行緒複製檔案;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Test {
public static void main(String[] args) {
//這裡我們使用4個執行緒同時複製一個檔案---複製一個視訊
// 先獲取檔案的長度 length()
File file = new File("D:\\執行緒.wmv");
long l = file.length();
//平均每段長度:長度/4
int avgLength = (int)l/4;
// 建立四個執行緒物件 傳遞 起始 和終止位置
//注意:最後一段的結束位置:因為--長度/4--不一定能不除盡,可能有餘數,所以必須在最後一節將剩餘的都算上來
MyThead thead = new MyThead(0, avgLength-1);
MyThead thead2 = new MyThead(avgLength, 2*avgLength-1);
MyThead thead3 = new MyThead(avgLength*2, 3*avgLength-1);
MyThead thead4 = new MyThead(3*avgLength, (int)file.length()-1);
// 啟動執行緒
thead.start();
thead2.start();
thead3.start();
thead4.start();
}
}
//子執行緒
class MyThead extends Thread{
int start;
int end;
public MyThead(int start,int end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"啟動了");
// 根據位置賦值檔案
RandomAccessFile read = null;
RandomAccessFile write = null;
try {
read = new RandomAccessFile(new File("D:\\執行緒.wmv"), "rw");
write = new RandomAccessFile(new File("D:\\執行緒2.wmv"), "rw");
// 2 設定讀寫位置
read.seek(start);
write.seek(start);// 指定位置開始讀寫
// 讀過的長度與要讀的長度相等 則此段落複製完畢
int length = end-start+1;// 每個執行緒要讀的長度
int readLength = 0;// 已經讀了的長度
byte[] bs = new byte[1024];
while(true){
//因為每段要複製的長度不一定恰好是1024的整數倍,夠1024時,直接讀寫即可;不滿1024時,有多少就讀多少
//因此這裡需要將剩餘檔案長度與1024進行比較
// 判斷剩餘位元組個數是否小於1024---1024為byte陣列中定義的長短
// 如果不小 正常讀取1024 4097
// 如果小於 只讀 剩餘的 總長度-讀取了的長度
if(length-readLength<1024){
read.read(bs, 0, length-readLength);// 不夠1024的時候單獨讀一次
write.write(bs, 0, length-readLength);
break;
}else{
// 剩餘需要讀的內容 大於等於1024
read.read(bs);
write.write(bs, 0, 1024);
readLength+=1024;
}
}
System.out.println(Thread.currentThread().getName()+"複製完畢");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(read!=null){
try {
read.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(write!=null){
try {
write.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}