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;
            }
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值