java 基础之图片的多线程处理和大文件的多线程拷贝

图片的多线程处理

public class PhotoHandle {
    public static void main(String[] args) {
        File file = new File("D:\\photo.bmp");
        photoHandle(file, 4);//把文件分成4个线程来处理
    }
    public static void photoHandle(File file, int threadNumber) {
        long length = file.length();
        long unitLength = length/threadNumber;//把图片长度按线程数等分
        for(int i=0; i<threadNumber; i++){
            long begin = 54;//图片一开始都不从零开始的
            long end = length;
            if (i != 0){
                begin = unitLength*i;
            }
            if(i!=threadNumber-1){
                end = unitLength*(i+1)-1;
            }
            String name = "线程"+i;
            MyThread myThreads = new MyThread(name, file, begin, end);
            new Thread(myThreads).start();
            System.out.println(name + "已开启");
        }
    }
}
复制代码

MyThread类

public class MyThread implements Runnable {
    private String name;//线程名
    private File file;//文件名
    private long begin;//起始位置
    private long end;//读取的结束位置
    public MyThread(String name, File file, long begin, long end) {
        this.name = name;
        this.file = file;
        this.begin = begin;
        this.end = end;
    }

    @Override
    public void run() {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "rw");
            raf.seek(begin);// raf指针定位到最开始
            while (begin <= end) {//还没到最后,则继续
                int i = 255 - raf.read();
                raf.seek(raf.getFilePointer() - 1);// 或raf.seek(begin)
                raf.write(i);
                begin++;
            }
            System.out.println(name + "拷贝完成!");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            IOUtils.closeRandomAccessFile(raf);
        }
    }
}
复制代码

多线程分段示意图如下

此图同样适用于下例的文件拷贝

(大)文件的的多线程拷贝

public class MultiThreadCopy{
    public static void main(String[] args) {
        File sourceFile = new File("E:\\javaIO\\myeclipse.exe");//源文件地址
        File targetDir = new File("e:/javaFile");//目标文件地址
        int threadNumber = 4;
        copyFile(sourceFile, targetDir, threadNumber);
    }

    public static void copyFile(File sourceFile, File targetDir, int threadNumber) {
        // TODO Auto-generated method stub
        if(!targetDir.exists()){
            targetDir.mkdirs();
        }
        File targetFile = new File(targetDir, sourceFile.getName());
        long length = sourceFile.length();
        long unitLength = length/threadNumber;
        for(int i=0; i<threadNumber; i++){
            long begin = 0;
            long end = length;
            if(i!=0){
                begin = unitLength*i;
            }
            if(i!=threadNumber-1){
                end = unitLength*(i+1)-1;
            }
            String name = "线程"+i;
            new MyThread(name, sourceFile, targetFile, begin, end).start();
            System.out.println(name+"启动完成!");
        }
    }
}
复制代码

MyThread类

public class MyThread extends Thread{
    private String name;
    private File sourceFile;
    private File targetDir;
    private long begin;
    private long end;
    public MyThread(String name, File sourceFile, File targetDir, long begin, long end) {
        this.name = name;
        this.sourceFile = sourceFile;
        this.targetDir = targetDir;
        this.begin = begin;
        this.end = end;
    }
    @Override
    public void run() {
        //定义读写的文件访问流
        RandomAccessFile rafRead = null;
        RandomAccessFile rafWrite = null;
        try {
            rafRead = new RandomAccessFile(sourceFile, "r");
            rafWrite = new RandomAccessFile(targetDir, "rw");
            //设置文件指针的开始位置和文件长度
            rafWrite.setLength(end);
            rafRead.seek(begin);
            rafWrite.seek(begin);
            int buffSize = 1024*6;
            byte[] buff = new byte[buffSize];
            while((begin+buffSize)<=end){
                //把数据读入到buff缓冲数组中
                rafRead.read(buff);
                //把buff缓冲数组的数据写入到目标文件
                rafWrite.write(buff);
                //起始位置再向前移
                begin+=buffSize;
            }
            //begin+buffSize超出了每一段的结尾,最后那一撮另外读
            long lastSize = end-begin;
            rafRead.read(buff, 0, (int) lastSize);
            rafWrite.write(buff, 0, (int) lastSize);
            System.out.println(this.name+"拷贝完成!");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            IOUtils.closeRandomAccessFile(rafRead);
            IOUtils.closeRandomAccessFile(rafWrite);
        }
    }
}
复制代码

IOUtils工具类

public class IOUtils {
    public static void closeInputStream(InputStream is){//传入的是具体的子类
        if (is != null){
            try {
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            is = null;
        }
    }
    public static void closeOutputStream(OutputStream os){
        if (os != null){
            try {
                os.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            os = null;
        }
    }
    public static void closeReader(Reader reader){
        if (reader != null){
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            reader = null;
        }
    }
    public static void closeWriter(Writer writer){
        if (writer != null){
            try {
                writer.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            writer = null;
        }
    }
    public static void closeRandomAccessFile(RandomAccessFile raf){
        if (raf != null){
            try {
                raf.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            raf = null;
        }
    }
}复制代码

转载于:https://juejin.im/post/5a45d64f6fb9a0450909d414

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值