学习研究断点续传的工具类

package com.hangxin.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
/**
 * 断点续传技术
 *
 */
public class FileDuanDianXuChuanUtil {
    

   public static void main(String[] args) {
       File source  = new File("C:\\Users\\cailun\\Desktop\\接口v1.1.doc");
       File dest = new File( "C:\\Users\\cailun\\Desktop\\接口v2.2.doc" );
       DuanDianFileProcess p1 =  new DuanDianFileProcess();
       p1.setSource(source);
       p1.setDest(dest);
       DuanDianFileProcess p2 = duandianxuchuan(p1);
       System.out.println(p2);
       DuanDianFileProcess p3 = duandianxuchuan(p2);
       System.out.println(p3);
     
       
  }
    
    
   
   public static DuanDianFileProcess duandianxuchuan(DuanDianFileProcess duanDianFileProcess)  {
       boolean startCopyBool = duanDianFileProcess.isStartCopyBool();
       try {
        if(startCopyBool){
               File source = duanDianFileProcess.getSource();
               File dest = duanDianFileProcess.getDest();
               if(dest.exists()){
                   dest.delete();
                   Thread.sleep(200);
               } 
               duanDianFileProcess = startCopyFile(source,dest);
           }else{
               duanDianFileProcess  = keepCopyFile(duanDianFileProcess);
           }
        } catch (InterruptedException e) {
            duanDianFileProcess = new DuanDianFileProcess();
            duanDianFileProcess.setCopyMsg(ProcessExceptions.threadErrorEx);
        }
        return duanDianFileProcess;
   }
   
   
    
    public static DuanDianFileProcess startCopyFile(File source,File dest){
        DuanDianFileProcess duanDianFileProcess = new DuanDianFileProcess();
        try {
            long position = 0L;
            String sourceMD5 = getFileMD5(source);
            FileInputStream fis = new FileInputStream(source);
            FileOutputStream fos = new FileOutputStream(dest);
            byte [] bs = new byte[1];
            while(( fis.read(bs))!=-1){
                fos.write(bs);
                if(position==2000){
                    break;
                }
                position++;
            }
            duanDianFileProcess.setSource(source);
            duanDianFileProcess.setDest(dest);
            duanDianFileProcess.setPosition(position);
            String destMD5 = getFileMD5(dest);
            position=dest.length();
            duanDianFileProcess.setSourceMD5(sourceMD5);
            duanDianFileProcess.setDestMD5(destMD5);
            if(sourceMD5.equals(destMD5)){
                duanDianFileProcess.setAllCopyBool(true);
            }else {
                duanDianFileProcess.setAllCopyBool(false);
            }
            duanDianFileProcess.setStartCopyBool(false);
            fos.flush();
            fos.close();
            fis.close();
        } catch (FileNotFoundException e) {
             duanDianFileProcess.setCopyMsg(ProcessExceptions.sourcefileNotFoundEx);
             return  duanDianFileProcess;
        } catch (IOException e) {
             duanDianFileProcess.setCopyMsg(ProcessExceptions.destfileErrorEx);
             return  duanDianFileProcess;
        }
        return duanDianFileProcess;
    }
    
    public static DuanDianFileProcess keepCopyFile(DuanDianFileProcess duanDianFileProcess) {
        duanDianFileProcess.setStartCopyBool(false);
        File source = duanDianFileProcess.getSource();
        File dest = duanDianFileProcess.getDest();
        if(!source.exists()){
             duanDianFileProcess.setCopyMsg(ProcessExceptions.sourcefileNotFoundEx);
             return  duanDianFileProcess;
        }
        if(!dest.exists()){
             duanDianFileProcess.setCopyMsg(ProcessExceptions.destfileNotFoundEx);
             return  duanDianFileProcess;
        }
        try {
            RandomAccessFile readFile = new RandomAccessFile(source, "rw");
            RandomAccessFile writeFile = new RandomAccessFile(dest, "rw");
            long position = duanDianFileProcess.getPosition();
            readFile.seek(position);
            writeFile.seek(position);
            byte [] bs = new byte[1];
            while((readFile.read(bs))!=-1){
                writeFile.write(bs);
                position++;
            }
            String destMD5 = getFileMD5(dest);
            String sourceMD5 = duanDianFileProcess.getSourceMD5();
            duanDianFileProcess.setPosition(position);
            if(sourceMD5.equals(destMD5)){
                duanDianFileProcess.setAllCopyBool(true);
            }else {
                duanDianFileProcess.setAllCopyBool(false);
            }
            duanDianFileProcess.setDestMD5(destMD5);
        } catch (FileNotFoundException e) {
             duanDianFileProcess.setCopyMsg(ProcessExceptions.destfileErrorEx);
             return  duanDianFileProcess;
        } catch (IOException e) {
             duanDianFileProcess.setCopyMsg(ProcessExceptions.destfileErrorEx);
             return  duanDianFileProcess;
        }
        return duanDianFileProcess;
    }
    
    
    
    public static String getFileMD5(File file){
        try {
            MessageDigest MD5 = MessageDigest.getInstance("MD5");
            FileInputStream fis = new FileInputStream(file);
            byte [] bs = new byte[1];
            while( fis.read(bs)!=-1 ){
                MD5.update(bs);
            }
            fis.close();
            return new String(Hex.encodeHex(MD5.digest()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
}

class ProcessExceptions   {
     
    public static String sourcefileNotFoundEx = "源文件未找到";
    public static String destfileNotFoundEx = "目标文件未找到";
    public static String destfileErrorEx ="目标文件已经损坏";
    public static String threadErrorEx ="线程错误";

}


class DuanDianFileProcess{
    private File source;//源文件
    private File dest;//目标文件
    private long position;//已经copy的字节数
    private String sourceMD5;//源文件的MD5值
    private String destMD5;//目标文件的MD5值
    private boolean  allCopyBool = false;//是否copy完成
    private boolean startCopyBool = true;//是否是刚开始拷贝
    private String copyMsg ;//拷贝信息
    
    
    public File getSource() {
        return source;
    }
    public void setSource(File source) {
        this.source = source;
    }
    public File getDest() {
        return dest;
    }
    public void setDest(File dest) {
        this.dest = dest;
    }
     
    public long getPosition() {
        return position;
    }
    public void setPosition(long position) {
        this.position = position;
    }
    public String getSourceMD5() {
        return sourceMD5;
    }
    public void setSourceMD5(String sourceMD5) {
        this.sourceMD5 = sourceMD5;
    }
    public String getDestMD5() {
        return destMD5;
    }
    public void setDestMD5(String destMD5) {
        this.destMD5 = destMD5;
    }
    public boolean isAllCopyBool() {
        return allCopyBool;
    }
    public void setAllCopyBool(boolean allCopyBool) {
        this.allCopyBool = allCopyBool;
    }
    public boolean isStartCopyBool() {
        return startCopyBool;
    }
    public void setStartCopyBool(boolean startCopyBool) {
        this.startCopyBool = startCopyBool;
    }
    public String getCopyMsg() {
        return copyMsg;
    }
    public void setCopyMsg(String copyMsg) {
        this.copyMsg = copyMsg;
    }
    @Override
    public String toString() {
        return "DuanDianFileProcess [source=" + source + ", dest=" + dest
                + ", position=" + position + ", sourceMD5=" + sourceMD5
                + ", destMD5=" + destMD5 + ", allCopyBool=" + allCopyBool
                + ", startCopyBool=" + startCopyBool + ", copyMsg=" + copyMsg
                + "]";
    }
    
    
}

 参考网上的写的断点续传的工具类。

主要思想:对源文件和目标文件进行封装,记录传输的位置,使用RandomAccessFile 类,进行再写入。

操作时注意文件流的状态。捕获异常之后重置封装类。就可以在调用了。

未经过实际检验,只是本人测试成功。仅供各位参考。

posted @ 2018-12-28 16:53  和平鸽  阅读(429)  评论(0编辑  收藏  举报