欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java多线程复制文件的实例代码

程序员文章站 2023-11-24 15:27:58
复制代码 代码如下: package com.test; import java.io.filenotfoundexception;  imp...

复制代码 代码如下:
 
package com.test; 
import java.io.filenotfoundexception; 
import java.io.ioexception; 
import java.io.randomaccessfile; 

public class filecoper { 
    private static final string _origin_file_mode = "r"; 

      
     private static final string _target_file_mode = "rw"; 

     private static long time1 = 0l; 
     private string originfilename; 

      
     private string targetfilename; 

      
     private randomaccessfile originfile; 

      
     private randomaccessfile targetfile; 

      
     private int threadcount; 

      
     private static int totalthreadcount = 0; 

     private static int executedcount = 0; 

     public filecoper() { 
      this.threadcount = 1; 
      totalthreadcount = this.threadcount; 
     } 

     public filecoper(string originfile, string targetfile) { 
      try { 
       this.originfilename = originfile; 
       this.targetfilename = targetfile; 
       this.originfile = new randomaccessfile((originfile), filecoper._origin_file_mode); 
       this.targetfile = new randomaccessfile((targetfile), filecoper._target_file_mode); 
       this.threadcount = 1; 
       totalthreadcount = this.threadcount; 
      } catch (filenotfoundexception e) { 
       e.printstacktrace(); 
      } 
     } 

     public filecoper(string originfile, string targetfile, int threadcount) { 
      try { 
       this.originfilename = originfile; 
       this.targetfilename = targetfile; 
       this.originfile = new randomaccessfile((originfile), filecoper._origin_file_mode); 
       this.targetfile = new randomaccessfile((targetfile), filecoper._target_file_mode); 
       this.threadcount = 1; 
       totalthreadcount = this.threadcount; 
      } catch (filenotfoundexception e) { 
       e.printstacktrace(); 
      } 
     } 

      
     public void init(string originfile, string targetfile) throws exception { 
      this.originfilename = originfile; 
      this.targetfilename = targetfile; 
      this.originfile = new randomaccessfile((originfile), filecoper._origin_file_mode); 
      this.targetfile = new randomaccessfile((targetfile), filecoper._target_file_mode); 
      this.threadcount = 1; 
      totalthreadcount = this.threadcount; 
     } 

      
     public void init(string originfile, string targetfile, int threadcount) throws exception { 
      this.originfilename = originfile; 
      this.targetfilename = targetfile; 
      this.originfile = new randomaccessfile((originfile), filecoper._origin_file_mode); 
      this.targetfile = new randomaccessfile((targetfile), filecoper._target_file_mode); 
      this.threadcount = threadcount; 
      totalthreadcount = this.threadcount; 
     } 

      
     public void init(randomaccessfile originfile, randomaccessfile targetfile) throws exception { 
      this.originfile = originfile; 
      this.targetfile = targetfile; 
      this.threadcount = 1; 
      totalthreadcount = this.threadcount; 
     } 

      
     public void init(randomaccessfile originfile, randomaccessfile targetfile, int threadcount) throws exception { 
      this.originfile = originfile; 
      this.targetfile = targetfile; 
      this.threadcount = threadcount; 
      totalthreadcount = this.threadcount; 
     } 

      
     public static synchronized void finish() { 
      filecoper.executedcount ++; 

      system.out.println("总线程【" + filecoper.totalthreadcount + "】,已经完成【" + filecoper.executedcount + "】个线程的复制!!!"); 
      if (filecoper.totalthreadcount == filecoper.executedcount){ 
          long time2 = system.currenttimemillis(); 
          system.out.println("花费时长:"+(time2-time1)); 
           system.out.println("所有【" + filecoper.totalthreadcount + "】线程复制完成!!!"); 
      } 
     } 

      
     public void start() throws exception { 
      if (this.originfile.length() == 0) 
       return; 
      if (this.threadcount == 0) 
       this.threadcount = 1; 
      // 设置目标文件大小  
      this.targetfile.setlength(this.originfile.length()); 
      this.targetfile.seek(0); 
      this.originfile.seek(0); 
      time1 = system.currenttimemillis(); 
      system.out.println(this.originfile.length()); 
      // 把文件分块,每一块有一对值:当前块在文件中的起始位置和结束位置  
      long[][] splits = new long[this.threadcount][2]; 
      long originfilelength = this.originfile.length(); 
      int startpos = 0; 
      for (int i = 0; i < this.threadcount; i++) { 
       splits[i][0] = 0; 
       splits[i][1] = 0; 
       if (i == 0) { 
        splits[i][0] = 0; 
        splits[i][1] = originfilelength / this.threadcount; 

       } else if (i == this.threadcount - 1) { 
        // 注意:此处不能加1,如果加1,线程多文件就会出现乱码  
        // splits[i][0] = startpos + 1;  
        splits[i][0] = startpos; 
        splits[i][1] = originfilelength; 
       } else { 
        // 注意:此处不能加1,如果加1,线程多文件就会出现乱码  
        // splits[i][0] = startpos + 1;  
        splits[i][0] = startpos; 
        splits[i][1] = startpos + originfilelength / this.threadcount; 
       } 
       startpos += originfilelength / this.threadcount; 
       // system.out.println(splits[i][0] + " " + splits[i][1]);  

       coper fc = new coper("thread-" + i); 
       fc.init(this.originfile, this.targetfile, splits[i][0], splits[i][1]); 
       fc.setoriginfilename(this.originfilename); 
       fc.settargetfilename(this.targetfilename); 
       fc.start(); 
      } 
     } 

      
     public void startnew() throws exception { 
      if (this.originfile.length() == 0) 
       return; 
      // 设置目标文件大小  
      this.targetfile.setlength(this.originfile.length()); 
      this.targetfile.seek(0); 
      this.originfile.seek(0); 

      long startposition; 
      long endposition; 
      long block = this.originfile.length() / 1029; 

      if (block <= 1) 
       this.threadcount = 1; 

      for (int i = 0; i < this.threadcount; i++) { 
       // 定义每次转移的长度  
       startposition = i * 1029 * (block / this.threadcount); 
       endposition = (i + 1) * 1029 * (block / this.threadcount); 
       if (i == (this.threadcount - 1)) 
        endposition = this.originfile.length(); 
       coper fc = new coper("thread-" + i); 
       fc.init(this.originfile, this.targetfile, startposition, endposition); 
       fc.setoriginfilename(this.originfilename); 
       fc.settargetfilename(this.targetfilename); 
       fc.start(); 

      } 
     } 

     private class coper extends thread { 

       
      private string originfilename; 

       
      private string targetfilename; 

      private randomaccessfile originfile; 

       
      private randomaccessfile targetfile; 

       
      private string threadid; 

       
      private long startposition; 

       
      private long endposition; 

       
      private long blockcapacity; 

       
      public void setoriginfilename(string originfilename) { 
       this.originfilename = originfilename; 
      } 

       
      public void settargetfilename(string targetfilename) { 
       this.targetfilename = targetfilename; 
      } 

      public coper(string threadid) { 
       this.threadid = threadid; 
      } 

       
      public void init(randomaccessfile originfile, randomaccessfile targetfile, long startposition, long endposition) throws exception { 
       this.originfile = originfile; 
       this.targetfile = targetfile; 
       this.startposition = startposition; 
       this.endposition = endposition; 
       this.blockcapacity = this.endposition - this.startposition; 
      } 

      public void run() { 
       // system.out.println(this.threadid + " 启动,开始复制文件【" +  
       // this.originfilename + "】中的文件块【" + this.startposition + "," +  
       // this.endposition + "】到目标文件【" + this.targetfilename + "】中...");  
       synchronized (this.originfile) { 
        try { 
         // 记录当前拷贝的字节数  
         int copycount = 0; 
         // 数据拷贝的启示偏移量  
         long offset = this.startposition; 
         byte[] b = new byte[16 * 1024 * 1024]; 
         // 动态设置一次读取的字节数缓冲  
         long blocksize = 0; 
         while (copycount < this.blockcapacity) { 
          this.originfile.seek(offset); 
          if (this.blockcapacity - copycount > 16 * 1024 * 1024) 
           blocksize = 16 * 1024 * 1024; 
          else 
           blocksize = this.blockcapacity - copycount; 
          if (blocksize > this.blockcapacity - copycount) 
           blocksize = this.blockcapacity - copycount; 
          int count = this.originfile.read(b, 0, (int) blocksize); 
          synchronized (this.targetfile) { 
           try { 
            if (copycount == 0) 
             this.targetfile.seek(offset); 
            else 
             this.targetfile.seek(offset + 1); 

            this.targetfile.write(b, 0, count); 
           } catch (ioexception e) { 
            e.printstacktrace(); 
           } 
          } 
          // 增加拷贝的字节数  
          copycount += count; 
          // 拷贝其实【偏移量下移  
          offset += count; 
         } 
        } catch (ioexception e) { 
         e.printstacktrace(); 
        } 
       } 
       // system.out.println(this.threadid + " 复制文件【" + this.originfilename  
       // + "】中的文件块【" + this.startposition + "," + this.endposition +  
       // "】到目标文件【" + this.targetfilename + "】完成!");  

       // 通知主线程,当前线程完成复制工作  
       filecoper.finish(); 
      } 

     } 

     public static void main(string[] args) throws exception { 
      filecoper fc = new filecoper(); 
      fc.init("e:/initialdata_zhihuan.sql", "e:/initialdata_zhihuan2.sql", 30); 
      //fc.init("d:/valueadd_11.txt", "d:/valueadd_111.txt", 100);  
      // fc.init("d:\tools\music\做你的爱人.mp3", "d:/做你的爱人_5.mp3", 10);  
      //fc.init("e:\电影\最黑暗侵袭.rmvb", "d:/最黑暗侵袭_1.rmvb", 100);  

     /* // 读入键盘输入
      bufferedreader br = new bufferedreader(new inputstreamreader(system.in));
      // 文件来源
      string originfile;
      // 文件目标
      string targetfile;
      system.out.println("【源文件、目标文件、线程数】");
      system.out.print("要复制的源文件:");
      originfile = br.readline();
      system.out.print("文件复制到目标文件:");
      targetfile = br.readline();
      system.out.print("切分线程数:");
      int threadcount = integer.parseint(br.readline());
      fc.init(originfile, targetfile, threadcount);*/ 
      // fc.startnew();  
      long time1 = system.currenttimemillis(); 
      fc.start(); 
      long time2 = system.currenttimemillis(); 
      system.out.println(time2-time1); 
     }