使用多线程去复制一个文件,我们可以指定文件名和线程数

来源:互联网 发布:国家网络风险评估标准 编辑:程序博客网 时间:2024/06/05 16:19



import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;


/**
 * 要求:使用多线程去复制一个文件,我们可以指定文件名和线程数
 *案例设计:
 *1:使用Java多线程模型
 *2:结合RandomAccessFile对文件进行并发分段写入。
 *达到多线程文件复制的目的。
 *案例实施步骤:1:获取复制文件的大小(字节数)
 *2:确定每个线程要下载的数据大小。
 *3:确定每个线程的下载起始位置
 *4:确定每个线程下载结束位置。
 *5:通过多线程来并发下载。
 */
public class MutiCopyFileDemo {


public static void main(String[] args) {

//因为每个人要复制的文件不同因此运行结果不同,3代表是3个线程下载。

MuticopyFileUtil copyFileUtil=new MuticopyFileUtil("D:\\新建文件夹\\新建文件夹\\有用的笔记.rar", "D:\\有用的笔记1.rar", 3);


copyFileUtil.copyFile();
}


}
class  MuticopyFileUtil{
private String  src;//源文件
private String  dst;//目标文件
private int threadSize;//开启多少个线程去复制源文件
//构造方法
public MuticopyFileUtil(String src, String dst, int threadSize) {
super();
this.src = src;
this.dst = dst;
this.threadSize = threadSize;
}
//声明一个复制文件的方法
public void  copyFile() {
File file=new File(src);//源文件的file对象
long fsize=file.length();//得到要复制文件的大小(字节数)
long block=fsize%threadSize==0?
fsize/threadSize:fsize/threadSize+1;//每个线程要下载的文件块的大小
for (int threadId= 0; threadId < threadSize; threadId++) {
new DownLoadThread(fsize, block, threadId).start();
//开启多个线程来进行文件的复制,每个线程都会复制一段区域

}
}
private class DownLoadThread extends Thread{
private long fsize;//文件大小
private long block;//每个线程要下载的字节数大小
private int threadId;//线程的ID号,从0开始
private int buffSize=1024*1024;//缓冲区的大小

public DownLoadThread(long fsize, long block, int threadId) {
super();
this.fsize = fsize;
this.block = block;
this.threadId = threadId;
}
//重写run方法
@Override
public void run() {
try {
RandomAccessFile reader=new RandomAccessFile(src, "r");
RandomAccessFile writer=new RandomAccessFile(dst, "rw");
long startPosition=threadId*block;
//某个线程下载的起始位置
//每个线程下载的结束位置
long endPosition=startPosition+block>fsize?fsize:startPosition+block;
reader.seek(startPosition);
writer.seek(startPosition);
byte[] buff=new byte[buffSize];//设置一个缓冲区
while (startPosition<endPosition) {
int len=0;
if (startPosition+buffSize<endPosition) {
//缓冲区放满了,但是还没有读完
len=reader.read(buff);//读满缓冲区
}else {
//把剩余部分填不满缓冲区的数据写入到缓冲区中
len=reader.read(buff,0,(int )(endPosition-startPosition));
}
startPosition+=len;//起始位置读一次就发生变化
writer.write(buff,0,len);
//把缓冲区中的数据写入指定文件的指定区域
System.out.println("线程:"+(threadId+1)+"下载:"+len+"字节");

}
reader.close();//释放资源
writer.close();
System.out.println("线程:"+(threadId+1)+"下载完毕");
} catch (IOException e) {
e.printStackTrace();
}

}

}

}


以三个线程为例

运行结果(仅供参考):













0 0
原创粉丝点击