java多線程復(fù)制文件的實(shí)例代碼
更新時(shí)間:2013年03月19日 11:06:50 作者:
java多線程復(fù)制文件的實(shí)例代碼,需要的朋友可以參考一下
復(fù)制代碼 代碼如下:
package com.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileCoper {
private static final String _ORIGIN_FILE_MODE = "r";
private static final String _TARGET_FILE_MODE = "rw";
private static long time1 = 0l;
private String originFileName;
private String targetFileName;
private RandomAccessFile originFile;
private RandomAccessFile targetFile;
private int threadCount;
private static int totalThreadCount = 0;
private static int executedCount = 0;
public FileCoper() {
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public FileCoper(String originFile, String targetFile) {
try {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public FileCoper(String originFile, String targetFile, int threadCount) {
try {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void init(String originFile, String targetFile) throws Exception {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public void init(String originFile, String targetFile, int threadCount) throws Exception {
this.originFileName = originFile;
this.targetFileName = targetFile;
this.originFile = new RandomAccessFile((originFile), FileCoper._ORIGIN_FILE_MODE);
this.targetFile = new RandomAccessFile((targetFile), FileCoper._TARGET_FILE_MODE);
this.threadCount = threadCount;
totalThreadCount = this.threadCount;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.threadCount = 1;
totalThreadCount = this.threadCount;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile, int threadCount) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.threadCount = threadCount;
totalThreadCount = this.threadCount;
}
public static synchronized void finish() {
FileCoper.executedCount ++;
System.out.println("總線程【" + FileCoper.totalThreadCount + "】,已經(jīng)完成【" + FileCoper.executedCount + "】個(gè)線程的復(fù)制?。?!");
if (FileCoper.totalThreadCount == FileCoper.executedCount){
long time2 = System.currentTimeMillis();
System.out.println("花費(fèi)時(shí)長(zhǎng):"+(time2-time1));
System.out.println("所有【" + FileCoper.totalThreadCount + "】線程復(fù)制完成?。?!");
}
}
public void start() throws Exception {
if (this.originFile.length() == 0)
return;
if (this.threadCount == 0)
this.threadCount = 1;
// 設(shè)置目標(biāo)文件大小
this.targetFile.setLength(this.originFile.length());
this.targetFile.seek(0);
this.originFile.seek(0);
time1 = System.currentTimeMillis();
System.out.println(this.originFile.length());
// 把文件分塊,每一塊有一對(duì)值:當(dāng)前塊在文件中的起始位置和結(jié)束位置
long[][] splits = new long[this.threadCount][2];
long originFileLength = this.originFile.length();
int startPos = 0;
for (int i = 0; i < this.threadCount; i++) {
splits[i][0] = 0;
splits[i][1] = 0;
if (i == 0) {
splits[i][0] = 0;
splits[i][1] = originFileLength / this.threadCount;
} else if (i == this.threadCount - 1) {
// 注意:此處不能加1,如果加1,線程多文件就會(huì)出現(xiàn)亂碼
// splits[i][0] = startPos + 1;
splits[i][0] = startPos;
splits[i][1] = originFileLength;
} else {
// 注意:此處不能加1,如果加1,線程多文件就會(huì)出現(xiàn)亂碼
// splits[i][0] = startPos + 1;
splits[i][0] = startPos;
splits[i][1] = startPos + originFileLength / this.threadCount;
}
startPos += originFileLength / this.threadCount;
// System.out.println(splits[i][0] + " " + splits[i][1]);
Coper fc = new Coper("thread-" + i);
fc.init(this.originFile, this.targetFile, splits[i][0], splits[i][1]);
fc.setOriginFileName(this.originFileName);
fc.setTargetFileName(this.targetFileName);
fc.start();
}
}
public void startNew() throws Exception {
if (this.originFile.length() == 0)
return;
// 設(shè)置目標(biāo)文件大小
this.targetFile.setLength(this.originFile.length());
this.targetFile.seek(0);
this.originFile.seek(0);
long startPosition;
long endPosition;
long block = this.originFile.length() / 1029;
if (block <= 1)
this.threadCount = 1;
for (int i = 0; i < this.threadCount; i++) {
// 定義每次轉(zhuǎn)移的長(zhǎng)度
startPosition = i * 1029 * (block / this.threadCount);
endPosition = (i + 1) * 1029 * (block / this.threadCount);
if (i == (this.threadCount - 1))
endPosition = this.originFile.length();
Coper fc = new Coper("thread-" + i);
fc.init(this.originFile, this.targetFile, startPosition, endPosition);
fc.setOriginFileName(this.originFileName);
fc.setTargetFileName(this.targetFileName);
fc.start();
}
}
private class Coper extends Thread {
private String originFileName;
private String targetFileName;
private RandomAccessFile originFile;
private RandomAccessFile targetFile;
private String threadId;
private long startPosition;
private long endPosition;
private long blockCapacity;
public void setOriginFileName(String originFileName) {
this.originFileName = originFileName;
}
public void setTargetFileName(String targetFileName) {
this.targetFileName = targetFileName;
}
public Coper(String threadId) {
this.threadId = threadId;
}
public void init(RandomAccessFile originFile, RandomAccessFile targetFile, long startPosition, long endPosition) throws Exception {
this.originFile = originFile;
this.targetFile = targetFile;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.blockCapacity = this.endPosition - this.startPosition;
}
public void run() {
// System.out.println(this.threadId + " 啟動(dòng),開始復(fù)制文件【" +
// this.originFileName + "】中的文件塊【" + this.startPosition + "," +
// this.endPosition + "】到目標(biāo)文件【" + this.targetFileName + "】中...");
synchronized (this.originFile) {
try {
// 記錄當(dāng)前拷貝的字節(jié)數(shù)
int copyCount = 0;
// 數(shù)據(jù)拷貝的啟示偏移量
long offSet = this.startPosition;
byte[] b = new byte[16 * 1024 * 1024];
// 動(dòng)態(tài)設(shè)置一次讀取的字節(jié)數(shù)緩沖
long blockSize = 0;
while (copyCount < this.blockCapacity) {
this.originFile.seek(offSet);
if (this.blockCapacity - copyCount > 16 * 1024 * 1024)
blockSize = 16 * 1024 * 1024;
else
blockSize = this.blockCapacity - copyCount;
if (blockSize > this.blockCapacity - copyCount)
blockSize = this.blockCapacity - copyCount;
int count = this.originFile.read(b, 0, (int) blockSize);
synchronized (this.targetFile) {
try {
if (copyCount == 0)
this.targetFile.seek(offSet);
else
this.targetFile.seek(offSet + 1);
this.targetFile.write(b, 0, count);
} catch (IOException e) {
e.printStackTrace();
}
}
// 增加拷貝的字節(jié)數(shù)
copyCount += count;
// 拷貝其實(shí)【偏移量下移
offSet += count;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// System.out.println(this.threadId + " 復(fù)制文件【" + this.originFileName
// + "】中的文件塊【" + this.startPosition + "," + this.endPosition +
// "】到目標(biāo)文件【" + this.targetFileName + "】完成!");
// 通知主線程,當(dāng)前線程完成復(fù)制工作
FileCoper.finish();
}
}
public static void main(String[] args) throws Exception {
FileCoper fc = new FileCoper();
fc.init("e:/InitialData_zhihuan.sql", "e:/InitialData_zhihuan2.sql", 30);
//fc.init("d:/ValueAdd_11.txt", "d:/ValueAdd_111.txt", 100);
// fc.init("D:\tools\music\做你的愛人.mp3", "d:/做你的愛人_5.mp3", 10);
//fc.init("E:\電影\最黑暗侵襲.rmvb", "d:/最黑暗侵襲_1.rmvb", 100);
/* // 讀入鍵盤輸入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 文件來源
String originFile;
// 文件目標(biāo)
String targetFile;
System.out.println("【源文件、目標(biāo)文件、線程數(shù)】");
System.out.print("要復(fù)制的源文件:");
originFile = br.readLine();
System.out.print("文件復(fù)制到目標(biāo)文件:");
targetFile = br.readLine();
System.out.print("切分線程數(shù):");
int threadCount = Integer.parseInt(br.readLine());
fc.init(originFile, targetFile, threadCount);*/
// fc.startNew();
long time1 = System.currentTimeMillis();
fc.start();
long time2 = System.currentTimeMillis();
System.out.println(time2-time1);
}
}
相關(guān)文章
mybatis抽取基類BaseMapper增刪改查的實(shí)現(xiàn)
目前項(xiàng)目當(dāng)中使用mapper.xml文件方式對(duì)數(shù)據(jù)庫進(jìn)行操作,但是每個(gè)里邊都有增/刪/改/查,為了方便開發(fā),把這些公共的代碼提取出來,不用當(dāng)做基類,不用每個(gè)Mapper文件都寫了,本文就詳細(xì)的介紹一下實(shí)現(xiàn)方法2021-09-09
java得到某年某周的第一天實(shí)現(xiàn)思路及代碼
某年某周的第一天,此功能如何使用java編程得到呢?既然有了問題就有解決方法,感興趣的朋友可以了解下本文,或許會(huì)給你帶來意想不到的收獲哦2013-01-01
java實(shí)現(xiàn)斐波那契數(shù)列的3種方法
這篇文章主要介紹了java實(shí)現(xiàn)斐波那契數(shù)列的3種方法,有需要的朋友可以參考一下2014-01-01
SpringBoot生成PDF的五種實(shí)現(xiàn)方法總結(jié)
這篇文章主要介紹了SpringBoot生成PDF的五種實(shí)現(xiàn)方法,在開發(fā)中經(jīng)常會(huì)遇到需要進(jìn)行對(duì)一些數(shù)據(jù)進(jìn)行動(dòng)態(tài)導(dǎo)出PDF文件,然后讓用戶自己選擇是否需要打印出來,這篇文章我們來介紹五種實(shí)現(xiàn)方法,需要的朋友可以參考下2024-10-10
mybatis 運(yùn)行時(shí)加載自定義mapper文件方式
這篇文章主要介紹了mybatis 運(yùn)行時(shí)加載自定義mapper文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
使用 Spring Boot 內(nèi)嵌容器 Undertow創(chuàng)建服務(wù)器的方法
Undertow是一個(gè)非常輕量并高性能的web server,它來自 JBoss。支持blocking和non-blocking兩種NIO API。接下來通過本文給大家介紹使用Spring Boot 內(nèi)嵌容器 Undertow創(chuàng)建服務(wù)器的方法,感興趣的朋友一起看看吧2017-11-11
一文詳解如何使用線程池來優(yōu)化我們的應(yīng)用程序
線程池是一種工具,但并不是適用于所有場(chǎng)景。在使用線程池時(shí),我們需要根據(jù)應(yīng)用程序的性質(zhì)、計(jì)算資源的可用性和應(yīng)用程序的需求進(jìn)行適當(dāng)?shù)呐渲?。本文主要介紹了如何使用線程池來優(yōu)化我們的應(yīng)用程序,需要的可以參考一下2023-04-04
解決IDEA Gradle構(gòu)建報(bào)錯(cuò)''Cause: zip END header not found''
這篇文章主要介紹了解決IDEA Gradle構(gòu)建報(bào)錯(cuò)"Cause: zip END header not found"的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02

