java文件断点续传

知兮丶青 续传
阅读(969) 2018-01-01
java文件断点续传
java文件断点续传

这是一个java断点续传功能简单例子,对新手可读性高。java的RandomAccessFile提供自由读取,可以实现文件断点续传功能。

何为断点续传,就是一个文件第一次未上传完毕,第二次可以从上次位置开始继续上传,第三次...,直至上传完毕。例如迅雷下载,这次下载不完,下次接着下载。


以下例子实现文件复制的断点复制,模拟第一次读到某点后断开,第二次读继续读取直至完毕。


TestFile.java

package com.weizhixi.test;

import java.io.*;

public class TestFile {

    private final static String ROOT_PATH = "C:/Users/XQ/Desktop/test/";

    //文件复制,支持断点续传功能
    public void copy(String src, String target) throws Exception {
        String tmp = target + ".tmp";
        File srcFile = new File(src);
        File targetFile = new File(target);
        File tmpFile = new File(tmp);
        //如果文件已经存在则不会创建
        srcFile.createNewFile();
        //判断目标文件不存在 且 临时文件不存在,则表示之前没有传送过文件
        if (!targetFile.exists() && !tmpFile.exists()) {
            //创建临时文件,如果文件已经存在则不会创建
            tmpFile.createNewFile();
            //开始传送操作
            RandomAccessFile raf_r = new RandomAccessFile(srcFile, "r");
            RandomAccessFile raf_w = new RandomAccessFile(tmpFile, "rw");
            int offset = 0;
            byte[] temp = new byte[1024];
            while ((offset = raf_r.read(temp)) != -1) {
                raf_w.write(temp, 0, offset);
                //模拟断点,当长度大于1000的时候模拟断点,并保存断位置,第二次运行再从当前断点后开始读。
                if (tmpFile.length() > 1000) {
                    //要得到当前指针位置
                    long pointer = raf_w.getFilePointer();
                    System.out.println("当前指针:" + pointer);
                    savePointer(pointer);//保存当前指针
                    raf_r.close();
                    raf_w.close();
                    System.exit(0);
                }
            }
        } else {
            if (targetFile.exists()) {
                System.out.println("文件上次已经传送成功!请删掉相应文件后从新测试!");
            } else {
                //判断一下两个文件是否一样
                if (srcFile.length() == tmpFile.length()) {//一样则不传
                    System.out.println("文件上次已经传送成功!");
                } else {//不一样则续传
                    //得到最近一次文件传送的断点位置
                    long pointer = getPointer();
                    RandomAccessFile raf_r = new RandomAccessFile(srcFile, "r");
                    RandomAccessFile raf_w = new RandomAccessFile(tmpFile, "rw");
                    raf_r.seek(pointer);//从指定位置后开始读
                    raf_w.seek(pointer);//从指定位置后开始写
                    int offset = 0;
                    byte[] temp = new byte[1024];
                    while ((offset = raf_r.read(temp)) != -1) {
                        raf_w.write(temp, 0, offset);
                    }
                    raf_r.close();
                    raf_w.close();
                    System.out.println("文件已经续传完毕!");
                }
                //上传成功后,修改临时文件为目标文件
                tmpFile.renameTo(targetFile);
                //删除指针
                deletePointer();
            }
        }
    }

    //保存指针位置
    public void savePointer(long pointer) throws Exception {
        FileOutputStream fos = new FileOutputStream(ROOT_PATH + "pointer");
        DataOutputStream dos = new DataOutputStream(fos);
        dos.writeLong(pointer);
        dos.close();
        fos.close();
    }

    //获得指针位置
    public long getPointer() throws Exception {
        FileInputStream fis = new FileInputStream(ROOT_PATH + "pointer");
        DataInputStream dis = new DataInputStream(fis);
        long len = dis.readLong();
        dis.close();
        fis.close();
        return len;
    }

    //删除指针文件
    public boolean deletePointer(){
        File pointer = new File(ROOT_PATH + "pointer");
        if(pointer.exists())
            return pointer.delete();
        return false;
    }

    public static void main(String[] args) throws Exception {
        TestFile t = new TestFile();
        String srcPath = ROOT_PATH + "1.png";
        String targetPath = ROOT_PATH + "2.png";
        t.copy(srcPath, targetPath);
    }

}


第一次运行:

生成 2.png.tmp (临时文件)

生成 pointer (记录断点续传位置)

如图1

第一次运行文件断点续传.png


第二次运行:

上传完成后,修改临时文件为正式目标文件名 2.png

删除 pointer 指针文件

如图2

第二次运行文件断点续传.png




原创文章,转载请注明出处:https://www.weizhixi.com/article/47.html