java多线程复制文件的实例代码
程序员文章站
2023-12-11 21:38:22
复制代码 代码如下: package com.test; import java.io.filenotfoundexception; imp...
复制代码 代码如下:
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 + "】,已经完成【" + filecoper.executedcount + "】个线程的复制!!!");
if (filecoper.totalthreadcount == filecoper.executedcount){
long time2 = system.currenttimemillis();
system.out.println("花费时长:"+(time2-time1));
system.out.println("所有【" + filecoper.totalthreadcount + "】线程复制完成!!!");
}
}
public void start() throws exception {
if (this.originfile.length() == 0)
return;
if (this.threadcount == 0)
this.threadcount = 1;
// 设置目标文件大小
this.targetfile.setlength(this.originfile.length());
this.targetfile.seek(0);
this.originfile.seek(0);
time1 = system.currenttimemillis();
system.out.println(this.originfile.length());
// 把文件分块,每一块有一对值:当前块在文件中的起始位置和结束位置
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,线程多文件就会出现乱码
// splits[i][0] = startpos + 1;
splits[i][0] = startpos;
splits[i][1] = originfilelength;
} else {
// 注意:此处不能加1,如果加1,线程多文件就会出现乱码
// 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;
// 设置目标文件大小
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++) {
// 定义每次转移的长度
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 + " 启动,开始复制文件【" +
// this.originfilename + "】中的文件块【" + this.startposition + "," +
// this.endposition + "】到目标文件【" + this.targetfilename + "】中...");
synchronized (this.originfile) {
try {
// 记录当前拷贝的字节数
int copycount = 0;
// 数据拷贝的启示偏移量
long offset = this.startposition;
byte[] b = new byte[16 * 1024 * 1024];
// 动态设置一次读取的字节数缓冲
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();
}
}
// 增加拷贝的字节数
copycount += count;
// 拷贝其实【偏移量下移
offset += count;
}
} catch (ioexception e) {
e.printstacktrace();
}
}
// system.out.println(this.threadid + " 复制文件【" + this.originfilename
// + "】中的文件块【" + this.startposition + "," + this.endposition +
// "】到目标文件【" + this.targetfilename + "】完成!");
// 通知主线程,当前线程完成复制工作
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;
// 文件目标
string targetfile;
system.out.println("【源文件、目标文件、线程数】");
system.out.print("要复制的源文件:");
originfile = br.readline();
system.out.print("文件复制到目标文件:");
targetfile = br.readline();
system.out.print("切分线程数:");
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);
}
}