java文件断点续传
阅读(1000)
2018-01-01
这是一个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

第二次运行:
上传完成后,修改临时文件为正式目标文件名 2.png
删除 pointer 指针文件
如图2

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