我用了四條輸入線程,加四條輸出線程,來拷貝源文件,
結果還是慢了電腦自帶的慢一大截。希望大神能給個超電腦的。。
下面是我用多線程重新做的大文件拷貝程序:
import java.io.IOException;
/*
* 將一個電影文件,拷貝到其他盤。模擬下載,要求使用多線程
* 分析:
* 1,通過File對象關聯源文件,並獲取其大小。
* 2,通過File對象創建一個和源文件大小相同的(空)文件
* 3,通過隨機流RandomAccessFile讀取源文件,
* 4,將讀取的數據寫入到輸出管道流PipedOutputStream,
* 5,管道讀取流PipedInputStream讀取輸出流中的數據,並通過隨機流寫入到目的文件中。
*
*/
public class TestTwo {
public static void main(String[] args) throws IOException {
Copy.copy("C:\\Mon.mp4","C:\\Moncy.mp4");
}
}
Copy工具類進行拷貝操作:
import java.io.File;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
public class Copy {
public static void main(String[] args) {
}
public static boolean copy(String source, String destination) throws IOException {
File socefile = new File(source);
File destfile = new File(destination);
if(socefile.isHidden())
throw new RuntimeException("源文件不可操作");
//目的文件初始化,使其和源文件大小一致。
RandomAccessFile soceRaf = new RandomAccessFile(socefile,"r");
RandomAccessFile destRaf = new RandomAccessFile(destfile,"rwd");
destRaf.setLength(soceRaf.length());
long index = soceRaf.getFilePointer();
soceRaf.close();
destRaf.close();
//把源文件切成4段,每段的最小的(最接近負無窮大)double 值,該值大於等於參數,
//保證數據不丟失。最後一段單獨處理,因爲數據可能會小於len。
long len = (long) Math.ceil(socefile.length()/4);
for(int x=0 ; x<4 ; x++){
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
//爲了使每個線程都有一個自己獨立的指針,爲每個對象建立獨自的隨機流
new Thread(new PipedOut
(pos,new RandomAccessFile(socefile,"r"),index,len)).start();;
new Thread(new PipedIn
(pis,new RandomAccessFile(destfile,"rwd"),index,len)).start();
index = index + len ;
}
return true;
/*無限代碼,用於測試的
* PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
long len = soceRaf.length();
new Thread(new PipedOut(pos,soceRaf,index,len)).start();
new Thread(new PipedIn(pis,destRaf,index,len)).start();
*/
}
}
PipedOut :通過隨機流讀取,並寫入到管道流中:
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
public class PipedOut implements Runnable{
BufferedOutputStream pos;
RandomAccessFile soceRaf;
long index;
long len;
PipedOut(PipedOutputStream pos, RandomAccessFile soceRaf, long index, long len) {
super();
this.pos = new BufferedOutputStream(pos);
this.soceRaf = soceRaf;
this.index = index;
this.len = len;
}
public void run() {
try {
byte[] buf = new byte[1024*1024*20];
int length = 0 ;
soceRaf.seek(index);//設置指針位置
//如果沒有循環超出數據位置,或者在到結尾。
while(soceRaf.getFilePointer()<index+len){
if((length=soceRaf.read(buf))!=-1){
pos.write(buf,0,length);
pos.flush();
}
else
break;
}
//如果是因爲循環超出數據位置導致的結束,則計算出有效的數組長度
if(length==buf.length){
length =(int) ((long)length - ( soceRaf.getFilePointer()-(index+len) ));
System.out.println(length);
pos.write(buf,0,length);
}
pos.close();
soceRaf.close();
}
catch (IOException e) {
e.printStackTrace();
}
/*
* 無效代碼用於測試的
try {
byte[] buf = new byte[1024*100];
int length = 0 ;
soceRaf.seek(index);//設置指針位置
//如果沒有循環超出數據位置,或者在到結尾。
while((length=soceRaf.read(buf))!=-1){
pos.write(buf,0,length);
pos.flush();
}
pos.close();
soceRaf.close();
}
catch (IOException e) {
e.printStackTrace();
}
*/
}
}
PipedIn 從管道流中讀取數據,並通過任意流寫入到目的文件中:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.RandomAccessFile;
public class PipedIn implements Runnable {
BufferedInputStream pis;
RandomAccessFile destRaf;
long index;
long len;
PipedIn(PipedInputStream pis, RandomAccessFile destRaf, long index, long len) {
super();
this.pis =new BufferedInputStream(pis);
this.destRaf = destRaf;
this.index = index;
this.len = len;
}
public void run() {
try {
byte[] buf = new byte[1024*1024*20];
int length = 0 ;
destRaf.seek(index);//設置指針位置
//讀取管道流中的數據,並寫入目的文件中
while((length=pis.read(buf))!=-1){
destRaf.write(buf,0,length);
}
pis.close();
destRaf.close();
System.out.println("over");
} catch (IOException e) {
e.printStackTrace();
}
}
}
比起單線程切實是快樂好多倍,但是和電腦自帶的比起來,簡直就是滿滿的挫敗感。。。
感覺自己當初的懵懂的大志疑惑幻想,是怎麼的可笑,如果還有比windows更快更好的,windows一定早就用了吧?
換句話說,windows現在用的豈能不是最好最優的,,,
呵,我也只能帶着自己無知無畏最後的無奈匆匆一笑,希望在今後遇到問題能去進一步想想,少一些不切實際幻想,
有想法是好的,關鍵跟要有這樣的實力,敢於幻想,更要能加以辯論!