java文件断点续传
阅读(969)
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