综合应用题:多线程复制文件(知识点:多线程、随机读写流)

要求:使用多线程复制一个文件(使用多线程复制一个文件可以加快文件的复制速度)

代码:

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();
                }
            }

        }
    }
}











posted @ 2017-05-03 10:25  TCB_Java  阅读(231)  评论(0编辑  收藏  举报