精华内容
下载资源
问答
  • 2018-06-23 11:26:01

    昨天晚上做了个实验,用多个线程复制7个文件和单个线程复制7个文件(总共约1.7G)比较,代码如下:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    
    public class T3 {
    
    	public static void main(String[] args) throws IOException, InterruptedException {
    		
    		File path = new File("E:\\tmp\\1");
    		File[] listFiles = path.listFiles();
    		ExecutorService exec=Executors.newFixedThreadPool(listFiles.length);
    		CountDownLatch c = new CountDownLatch(listFiles.length);
    		System.out.println("begin copy");
    		long b=System.nanoTime();
    		one(listFiles,c);
    //		two(listFiles, exec,c);	
    		c.await();
    		long n=System.nanoTime();
    		System.out.println("copy over,times="+(n-b));
    	}
    	
    	public static void one(File[] listFiles,CountDownLatch c) throws IOException{
    		for(File f:listFiles){
    			FileInputStream fis=null;
    			FileOutputStream fos=null;
    			try{
    				 fis = new FileInputStream(f);
    				 fos = new FileOutputStream(new File("c://tmp//"+f.getName()));
    				byte[] bs=new byte[1024*1024*10];
    				int n=-1;
    				while((n=fis.read(bs))>0){
    					fos.write(bs, 0, n);
    				}
    			}finally{
    				if(fis!=null) fis.close();
    				if(fos!=null) fos.close();
    				System.out.println(Thread.currentThread().getName()+" copy "+f.getName()+" ok");
    				c.countDown();
    			}
    			
    		}
    	}
    	
    	public static void two(File[] files,ExecutorService exec,CountDownLatch c){
    		for(File f:files){
    //			exec.execute(new R(f,c));
    			new Thread(new R(f,c)).start();
    		}
    		exec.shutdown();
    	}
    
    }
    class R implements Runnable{
    	private File f;
    	private CountDownLatch c;
    	public R(File f,CountDownLatch c){
    		this.f=f;this.c=c;
    	}
    
    	@Override
    	public void run() {
    		FileInputStream fis=null;
    		FileOutputStream fos=null;
    		try{
    			 fis = new FileInputStream(f);
    			 fos = new FileOutputStream(new File("c://tmp//"+f.getName()));
    			byte[] bs=new byte[1024*1024];
    			int n=-1;
    			while((n=fis.read(bs))>0){
    				fos.write(bs, 0, n);
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    		}finally{
    			try{
    				if(fis!=null) fis.close();
    				if(fos!=null) fos.close();
    			}catch (Exception e){
    				e.printStackTrace();
    			}
    			System.out.println(Thread.currentThread().getName()+" copy "+f.getName()+" ok");
    			c.countDown();
    		}
    		
    	}
    	
    }

    多线程明显比单线程慢很多。

    打开任务管理器,单线程情况下,磁盘利用率已经99了,读写速度90M/s,于是降低读写速度byte[] bs=new byte[100];再次比较。单线程 磁盘利用率已经变为20左右,读写速度降到了20M/s. 多线程起初IO读写速度较高,但是7个线程都io的时候,利用率达到了99,读写速度受到限制,但是最后随着有的线程完成了任务,io读写速度又升上去了,最终多线程复制话费的时间少于单线程。

    因此想要多线程复制文件,要考虑IO读写速度,单线程磁盘利用率100了,再增加线程也没用。

    更多相关内容
  • Java 单线程复制文件和使用RandomAccessFile多线程复制文件的比较,对应博客地址为http://blog.csdn.net/zmichealchow/article/details/38687431
  • C#多线程复制代码: 1.运用线程和线程池的知识 2.可以实现 限制线程的数量 进行上传 3.用到FileStream类的读写功能 总之 大家可以参考一下!
  • Java利用多线程复制文件前言RandomAccessFile代码测试 前言 复制一个文件,是学习IO流时最基本的操作。你可以使用字节型文件流,也可以使用高级缓冲流。 但是,它们都是单线程的。 如果需要复制一个大型文件,单线程...

    Java利用多线程复制文件

    前言

    复制一个文件,是学习IO流时最基本的操作。你可以使用字节型文件流,也可以使用高级缓冲流。

    但是,它们都是单线程的。

    如果需要复制一个大型文件,单线程的复制一般而言是不能够充分发挥CPU以及内存的性能。这时候就需要利用多线程来复制文件。

    多线程的读:

    我们很自然地想到,利用FileInputStream类的skip()方法,可以跳着读,这就对多线程比较友好,启动多个线程,第一个线程读一部分,第二个线程跳过一部分字节再读,这没有问题。

    但是如果要写呢?我们知道FileOutputStream类是没有与skip类似的方法的,也就是说,它不能跳着写,这就很麻烦。

    这就意味着,如果需要利用多线程复制一个文件,那么首先得把这个文件利用多线程并发,读取并同时写入成多个文件碎片,然后再利用单线程去一一读取这些文件碎片,把它们的内容写入到一个完整的文件中。必要的话,最后再删除这些中间文件碎片。

    这个过程,复杂,且性能不高。涉及到两套读写,前面多线程读写,后面单线程读写。很显然这个过程虽然使用到了多线程但它不能提高性能,反而降低了性能。

    既然鸡肋点在于FileOutputStream不能跳着写,那么就找一个能跳着写的类吧。

    RandomAccessFile

    RandomAccessFile是java Io体系中功能最丰富的文件内容访问类。即可以读取文件内容,也可以向文件中写入内容。但是和其他输入/输入流不同的是,程序可以直接跳到文件的任意位置来读写数据。

    RandomAccessFile包含了以下两个方法来操作文件的记录指针:

    • long getFilePointer(); 返回文件记录指针的当前位置
    • void seek(long pos); 将文件记录指针定位到pos位置

    有了RandomAccessFile这个类,上面的问题就迎刃而解,因为它最大的好处就是可以实现从指定位置写入一些数据到文件中!

    顺便说一下它的构造方法:

    • RandomAccessFile(File file, String mode)
    • RandomAccessFile(String name, String mode)

    mode表示RandomAccessFile的访问模式,她有4个值:

    • “r”:只有读的权限,如果你试图去执行写入方法,则抛出IOException异常。
    • “rw”:有读和写 两个权限,如果该文件不存在,则会创建该文件。
    • “rws”:相对于”rw” 模式,还要求对文件内容或元数据的每个更新都同步写入到底层设备。
    • “rwd”:相对于”rw” 模式,还要求对文件内容每个更新都同步写入到底层设备。

    一般而言我们使用“r”和“rw”就够了,后面那两个我也不懂干嘛的。

    代码

    package testThread.file_threading;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    public class ThreadFileCopy extends Thread {
        private String srcFileStr;//源文件的路径
        private String desFileStr;//目标文件的路径 ,des --> destination目的地
        private long skipLen;//跳过多少个字节开始读/写
        private long workload;//总共要读/写多少个字节
        private final int IO_UNIT = 1024;//每次读写的基本单位(1024个字节)
    
        public ThreadFileCopy(String srcFileStr, String desFileStr, long skipLen, long workload) {
            this.srcFileStr = srcFileStr;
            this.desFileStr = desFileStr;
            this.skipLen = skipLen;
            this.workload = workload;
        }
        public void run(){
            FileInputStream fis = null;
            BufferedInputStream bis = null;//利用高级缓冲流,加快读的速度
            RandomAccessFile raf = null;
            try {
                fis = new FileInputStream(srcFileStr);
                bis = new BufferedInputStream(fis);
                raf = new RandomAccessFile(desFileStr,"rw");
                bis.skip(this.skipLen);//跳过一部分字节开始读
                raf.seek(this.skipLen);//跳过一部分字节开始写
                byte[] bytes = new byte[IO_UNIT];
                //根据总共需要复制的字节数 和 读写的基本单元 计算出一共需要读写的次数,利用读写次数控制循环
                long io_num = this.workload/IO_UNIT + 1;//因为workload/1024 很可能不能整除,会有余数
                if(this.workload % IO_UNIT == 0)
                    io_num--;//如果碰巧整除,读写次数减一
                //count表示读取的有效字节数,虽然count不参与控制循环结束,
                // 但是它能有效避免最后一次读取出的byte数组中有大量空字节写入到文件中,导致复制出的文件稍稍变大
                int count = bis.read(bytes);
                while (io_num != 0){
                    raf.write(bytes,0,count);
                    count = bis.read(bytes,0,count);//重新计算count的值
                    io_num--;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (fis != null)
                        fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (bis != null)
                        bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (raf != null)
                        raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    测试

    package testThread.file_threading;
    
    import java.io.File;
    
    public class TestMain {
        public static void main(String[] args) {
            int thread_num = 5;//创建5个线程读写
            String srcFileStr = "E:\\test\\123.flv";
            String desFileStr = "E:\\test\\thread.flv";
            File srcFile = new File(srcFileStr);
            long workload = srcFile.length()/thread_num;//总共要读/写多少个字节
            //用一个数组来存储每个线程跳过的字节数
            long[] skipLenArr = new long[thread_num];
            for(int i = 0;i<skipLenArr.length;i++){
                skipLenArr[i] = i*workload;
            }
            //用一个数组来存储所有的线程
            ThreadFileCopy[] tfcs = new ThreadFileCopy[thread_num];
            //初始化所有线程
            for(int i = 0;i<tfcs.length;i++){
                tfcs[i] = new ThreadFileCopy(srcFileStr,desFileStr,skipLenArr[i],workload);
            }
            //让所有线程进入就绪状态
            for(int i = 0;i<tfcs.length;i++){
                tfcs[i].start();
            }
            System.out.println("复制完毕!");
        }
    }
    
    展开全文
  • java多线程复制文件的实例代码,需要的朋友可以参考一下
  • 主要介绍了linux 下python多线程递归复制文件夹及文件夹中的文件,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有一个线程在工作。相当于还是...
  • Mysql多线程复制调整参数

    千次阅读 2017-12-25 11:51:41
    Mysql多线程复制调整参数

    1、配置从服务器上的多线程并行复制的参数(此处为实现多线程复制的重要参数)在数据库配置文件 my.cnf中设置

    slave-parallel-type=LOGICAL_CLOCK
    slave-parallel-workers=16             #16为设置的并发线程个数,之后根据项目对数据传输的具体要求再更改
    #一个 schema 下,slave_parallel_workers中的worker线程并发执行relay log中主库提交的事务
    master_info_repository= TABLE
    relay_log_info_repository= TABLE
    relay_log_recovery= ON

    注:变量slave-parallel-type可以有两个值

    DATABASE 为默认值,意为基于库的并行复制方式;

    LOGICAL_CLOCK:基于组提交的并行复制方式

    2、执行命令show processlist; 查看等待的线程.


    或者


    1、下面查看复制类型和并行数量配置

    mysql> show variables like 'slave_parallel_type';
    +---------------------+----------+
    | Variable_name  | Value |
    +---------------------+----------+
    | slave_parallel_type | DATABASE |
    +---------------------+----------+
    1 row in set (0.00 sec)

    当前的复制类型是 DATABASE,也就是统一数据库下只有一个线程进行复制,不能并行复制。


    mysql> show variables like 'slave_parallel_workers';
    +------------------------+-------+
    | Variable_name   | Value |
    +------------------------+-------+
    | slave_parallel_workers | 0  |
    +------------------------+-------+
    1 row in set (0.01 sec)

    当前并行工作的进程数是 0

    配置多线程

    1、停止从节点复制

    mysql> stop slave;
    Query OK, 0 rows affected (0.01 sec)

    2、设置复制类型为 LOGICAL_CLOCK

    mysql> set global slave_parallel_type= 'logical_clock' ;
    Query OK, 0 rows affected (0.00 sec)
    mysql> show variables like 'slave_parallel_type' ;
    + ---------------------+---------------+
    | Variable_name  | Value   |
    + ---------------------+---------------+
    | slave_parallel_type | LOGICAL_CLOCK |
    + ---------------------+---------------+
    1 row in set (0.01 sec)

    3、设置并行数量为 4
    mysql> set global slave_parallel_workers=4;
    Query OK, 0 rows affected (0.00 sec)
    mysql> show variables like 'slave_parallel_workers' ;
    + ------------------------+-------+
    | Variable_name   | Value |
    + ------------------------+-------+
    | slave_parallel_workers | 4  |
    + ------------------------+-------+
    1 row in set (0.00 sec)

    4、启动从节点复制

    mysql> start slave;
    Query OK, 0 rows affected (0.02 sec)

    5、查看一下当前工作的线程数

    mysql> show processlist;



    展开全文
  • 文件夹遍历与多线程复制文件

    热门讨论 2012-03-14 20:25:58
    改小程序主要练习: 1、文件夹非递归遍历 2、文件操作,实现对文件的复制 3、多线程复制文件 4、线程互斥(临界区) 5、MFC非模态对话框的创建和销毁
  • Java简单实现多线程复制文件

    千次阅读 2017-08-16 21:46:51
    #简单点 ...###开启多线程复制方法:线程个数,文件长度,源文件,目标文件,以参数形式传入,方法里用一个for循环去开辟新线程。 ###主方法:找到资源文件,调用开启多线程复制方法。import java.i
    • #简单点
      ##这里,我将所有的类写到一个Java文件中,方便梳理逻辑
      ##大概思路:
      ###复制线程:需要知道我们的线程从哪个位置开始复制,复制结束的位置,以及复制的源文件,需要复制的目标文件。
      ###开启多线程复制方法:线程个数,文件长度,源文件,目标文件,以参数形式传入,方法里用一个for循环去开辟新线程。
      ###主方法:找到资源文件,调用开启多线程复制方法。
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.RandomAccessFile;
    
    /**
     * 多线程复制文件
     */
    public class UsingThreadRandom {
        public static void main(String[] args) throws Exception {
            File file = new File("C:\\Users\\Administrator\\Desktop\\1.mp4");
            startThread(30, file.length(), "C:\\Users\\Administrator\\Desktop\\1.mp4",
                    "C:\\Users\\Administrator\\Desktop\\14.mp4");
        }
    
        /**
         * 开启多线程复制
         * 
         * @param threadnum
         *            线程数
         * @param fileLength
         *            文件大小(用于确认每个线程下载多少东西)
         * @param sourseFilePath
         *            源文件目录
         * @param targerFilePath
         *            目标文件目录
         */
        public static void startThread(int threadnum, long fileLength, String sourseFilePath, String targerFilePath) {
            System.out.println("================");
            System.out.println(fileLength);
            long modLength = fileLength % threadnum;
            System.out.println("modLength:" + modLength);
            long targetLength = fileLength / threadnum;
            System.out.println("targetLength:" + targetLength);
            for (int i = 0; i < threadnum; i++) {
                System.out.println((targetLength * i) + "-----" + (targetLength * (i + 1)));
                new FileWriteThread((targetLength * i), (targetLength * (i + 1)), sourseFilePath, targerFilePath).start();
            }
            if (modLength != 0) {
                System.out.println("最后的文件写入");
                System.out.println((targetLength * threadnum) + "-----" + (targetLength * threadnum + modLength));
                new FileWriteThread((targetLength * threadnum), targetLength * threadnum + modLength + 1, sourseFilePath,
                        targerFilePath).start();
            }
        }
    
        /**
         * 写线程:指定文件开始位置、目标位置、源文件、目标文件,
         */
        static class FileWriteThread extends Thread {
            private long begin;
            private long end;
            private RandomAccessFile soursefile;
            private RandomAccessFile targerFile;
    
            public FileWriteThread(long begin, long end, String sourseFilePath, String targerFilePath) {
                this.begin = begin;
                this.end = end;
                try {
                    this.soursefile = new RandomAccessFile(sourseFilePath, "rw");
                    this.targerFile = new RandomAccessFile(targerFilePath, "rw");
                } catch (FileNotFoundException e) {
                }
            }
    
            public void run() {
                try {
                    soursefile.seek(begin);
                    targerFile.seek(begin);
                    int hasRead = 0;
                    byte[] buffer = new byte[1];
                    while (begin < end && -1 != (hasRead = soursefile.read(buffer))) {
                        // System.out.println("hasRead:"+hasRead);
                        begin += hasRead;
                        targerFile.write(buffer, 0, hasRead);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        soursefile.close();
                        targerFile.close();
                    } catch (Exception e) {
                    }
                }
            }
        }
    }

    知识点:

    RandomAccessFile的seek()方法,用于指定文件位置。
    
    展开全文
  • java多线程复制文件

    2012-09-26 14:49:02
    java多线程复制文件
  • 多线程复制代码

    2014-04-19 09:50:48
    windows API SafeFileHandle 共享方式打开文件读和写。采用多线程方式并发读和写。实现多线程拷贝文件,提高复制速度。
  • 8*8的国际象棋上有八个皇后他们不能在同一行。同一列和斜对角和java中用多线程复制文件
  • MySQL主从复制的备库延迟一直是非常头疼的问题,MySQL5.7官方版推出多线程复制。但是无独有偶,前期测试MySQL5.7.12, 发现有CRASH的情况,所以一直没有着手研究测试MySQL5.7,提交官方BUG...
  • MySQL多线程复制

    千次阅读 2017-11-02 14:56:48
    MySQL的多线程复制不是一个新的东西,在5,7之前就已经有了,在5.7上进行了增强; 多线程复制可以减轻主从复制的延迟;一个线程只能针对一个数据库进行复制,显得有些鸡肋;大部分操作有可能都是对一个库的操作;...
  • 使用C实现多线程进行文件复制,在VC++6.0中可以运行
  • Java多线程实现复制文件

    千次阅读 2018-09-24 15:55:33
    * 多线程实现文件从一个目录复制到另一个目录 * @param sourceFile:给定源文件路径名 * @param desPath:复制点文件路径 * @return */ 代码实现如下: package com.tulun.thread; import java.io.File; import...
  • 多线程复制 轻松提高复制速度

    千次阅读 2011-10-20 15:59:17
    其实Windows7中已经内置了多线程复制的功能,可以大大提高复制速度,你有没有试过呢? Windows系统中的RoboCopy命令目录复制命令,不仅复制速度非常快,而且支持断点续传,甚至可以支持在制定的时间定时进行拷贝...
  • C语言实现 多线程文件传输

    热门讨论 2014-06-11 17:05:32
    本人在工作用的到c语言进程多线程工作,和多线程实现文件传输的功能,就网上寻找一份,供大家参考
  • RandomAccessFile随机文本,使用多线程处理复制文件
  • Android多线程文件夹下载及断点续传

    千次下载 热门讨论 2014-08-07 17:23:56
    Android实现网络多线程下载,断点续传,压缩包内有两个项目: downloadDemo:多线程下载 MulThreadDownloader:断点续传(网上别人的项目)
  • 多线程复制数组,并且统计计算数组的方差和指数函数,使用MFC多线程优化的做法是什么?
  • 基于MFC多线程的CopyFile

    热门讨论 2010-12-23 12:10:00
    VC基于MFC、多线程的文件复制对话框实现
  • MySQL并发复制系列二:多线程复制

    千次阅读 2016-04-18 13:13:26
    并发复制(Parallel Replication) 系列二: Enhanced Multi-threaded Slaves 作者:沃趣科技MySQL数据库工程师... 主从复制通过三个线程来完成,在master节点运行的binlog dump的线程,I/O线程和SQL线程运行在sla
  • 多线程复制,速度很快,还可以续传..对于超大文件的复制可以省很多时间..
  • SpringBoot 多线程下事务处理

    千次阅读 2021-01-22 14:49:22
    Springboot 在多线程下,处理事务; 目前很多开发的小伙伴们,都开始采用Springboot了,因为给我们带来了许多的开发便利,只需要我们关注编写逻辑代码。在工作中是会有很多小伙伴在项目逐步实用到多线程、线程池等...
  • 多线程复制文件显示进度

    千次阅读 2017-01-03 13:39:02
    * 使用多线程模拟迅雷下载的进度,用百分比表示,例如: 小黄人大眼萌,已下载xx% 龙门客栈,已下载xx% 黄飞鸿,已下载xx% * @author Administrator */ public class Down extends Thread { ...
  • Qt 负责文件的读写 qml负责显示进度,文件读写在子线程中进行。代码可以直接运行。
  • mysql主从复制配置 配置思路 1. 修改master和slave的配置文件,使用二进制日志,指定serverid 目的是让各自都有了自己的唯一标示,并以二进制文件格式进行交流 2. master中创建授权用户,查看二进制日志文件名,及...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 449,783
精华内容 179,913
关键字:

多线程复制