多線程
CopyFile.java
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
public class CopyFile implements Runnable {
// 源文件
private String source;
// 目標文件
private String target;
// 分塊總數
private int blockCount;
// 開始複製的塊序號
private int blockNo;
// 緩存大小
private int maxBuffSize = 1024 * 1024;
/**
* 將source文件分blockCount塊後的第blockNo塊複製至source
*
* @param source
* 源文件
* @param target
* 目標文件
* @param blockCount
* 文件分塊copy數
* @param blockNo
* 開始copy的塊序號
*/
public CopyFile(String source, String target, int blockCount, int blockNo) {
this.source = source;
this.target = target;
this.blockCount = blockCount;
this.blockNo = blockNo;
}
@Override
public void run() {
// 得到源文件
File file = new File(source);
// 得到源文件大小
long size = file.length();
// 根據文件大學及分塊總數計算出單個塊的大小
long blockLength = size / blockCount;
// 算出當前開始複製的位置
long startPosition = blockLength * blockNo;
// 實例化緩存
byte[] buff = new byte[maxBuffSize];
try {
// 從源文件得到輸入流
InputStream in = new FileInputStream(source);
// 得到目標文件的隨機訪問對象
RandomAccessFile raf = new RandomAccessFile(target, "rw");
// 將目標文件的指針偏移至開始位置
raf.seek(startPosition);
// 當前讀取的字節數
int curReadLength = 0;
// 累計讀取字節數的和
int totalReadLength = 0;
// 將源文件的指針偏移至開始位置
in.skip(startPosition);
// 依次分塊讀取文件
while ((curReadLength = in.read(buff)) > 0 && totalReadLength < blockLength) {
// 將緩存中的字節寫入文件中
raf.write(buff, 0, curReadLength);
// 累計讀取的字節數
totalReadLength += curReadLength;
}
// 關閉相關資源
raf.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadTest.java
public class ThreadTest {
// 源文件
private static String source;
// 目標文件
private static String target;
// 分塊數
private static int blockCount;
public static void main(String[] args) {
// 記錄開始時間
long beginTime = System.currentTimeMillis();
source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
target = "E:/多線程.exe";
blockCount = 3;
// 依次分塊進行文件copy
for (int i = 0; i <= blockCount; i++) {
// 實例化文件複製對象
CopyFile copyFile = new CopyFile(source, target, blockCount, i);
// 實例化線程
Thread th = new Thread(copyFile);
th.start();
try {
th.join();
} catch (Exception e) {
e.printStackTrace();
}
}
// 計算耗時
long entTime = System.currentTimeMillis();
// 輸出耗時
System.out.println("共用時:" + (entTime - beginTime) + "ms");
}
}
耗時:NIO方式複製
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
/***
* NIO方式複製文件
* @param args
*/
public class NIOCopy {
// 源文件
private static String source;
// 目標文件
private static String target;
public static void main(String[] args) {
long start = System.currentTimeMillis();
source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
target = "E:/NIO.exe";
File file = new File(source);
File file2 = new File(target);
long length = file.length();
int i = 0;
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(file);
out = new FileOutputStream(file2);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
while (true) {
if (inC.position() == inC.size()) {
outC.close();
inC.close();
break;
}
if ((inC.size() - inC.position()) < length)
length = inC.size() - inC.position();
inC.transferTo(inC.position(), length, outC);
inC.position(inC.position() + length);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("共用時"+(end - start)+"ms");
}
}
耗時:
普通複製:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CommonCopy {
// 源文件
private static String source;
// 目標文件
private static String target;
public static void main(String[] args) {
long start = System.currentTimeMillis();
source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
target = "E:/普通.exe";
File file = new File(source);
File file2 = new File(target);
int length = (int)file.length();
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(file);
out = new FileOutputStream(file2);
byte[] buffer = new byte[length];
int i = 0;
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("共用時"+(end - start)+"ms");
}
}
耗時:
普通複製文件的方法不太穩定,今天跳到了1KMS,但是仍然比多線程快???
一個疑問:爲什麼運用多線程複製文件反而不如普通方法複製?????