综合应用题:多线程复制文件(知识点:多线程、随机读写流)
要求:使用多线程复制一个文件(使用多线程复制一个文件可以加快文件的复制速度)
代码:
package 多线程复制文件;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Test {
public static void main(String[] args) {
//这里我们使用4个线程同时复制一个文件---复制一个视频
// 先获取文件的长度 length()
File file = new File("D:\\线程.wmv");
long l = file.length();
//平均每段长度:长度/4
int avgLength = (int)l/4;
// 创建四个线程对象 传递 起始 和终止位置
//注意:最后一段的结束位置:因为--长度/4--不一定能不除尽,可能有余数,所以必须在最后一节将剩余的都算上来
MyThead thead = new MyThead(0, avgLength-1);
MyThead thead2 = new MyThead(avgLength, 2*avgLength-1);
MyThead thead3 = new MyThead(avgLength*2, 3*avgLength-1);
MyThead thead4 = new MyThead(3*avgLength, (int)file.length()-1);
// 启动线程
thead.start();
thead2.start();
thead3.start();
thead4.start();
}
}
//子线程
class MyThead extends Thread{
int start;
int end;
public MyThead(int start,int end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"启动了");
// 根据位置赋值文件
RandomAccessFile read = null;
RandomAccessFile write = null;
try {
read = new RandomAccessFile(new File("D:\\线程.wmv"), "rw");
write = new RandomAccessFile(new File("D:\\线程2.wmv"), "rw");
// 2 设置读写位置
read.seek(start);
write.seek(start);// 指定位置开始读写
// 读过的长度与要读的长度相等 则此段落复制完毕
int length = end-start+1;// 每个线程要读的长度
int readLength = 0;// 已经读了的长度
byte[] bs = new byte[1024];
while(true){
//因为每段要复制的长度不一定恰好是1024的整数倍,够1024时,直接读写即可;不满1024时,有多少就读多少
//因此这里需要将剩余文件长度与1024进行比较
// 判断剩余字节个数是否小于1024---1024为byte数组中定义的长短
// 如果不小 正常读取1024 4097
// 如果小于 只读 剩余的 总长度-读取了的长度
if(length-readLength<1024){
read.read(bs, 0, length-readLength);// 不够1024的时候单独读一次
write.write(bs, 0, length-readLength);
break;
}else{
// 剩余需要读的内容 大于等于1024
read.read(bs);
write.write(bs, 0, 1024);
readLength+=1024;
}
}
System.out.println(Thread.currentThread().getName()+"复制完毕");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(read!=null){
try {
read.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(write!=null){
try {
write.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}