关于断点续传,关键在于"续",即断点之后,如何将未完成的工作接着进行下去,因此即需要在下载行为出现中断时记录下中断的位置信息,以便在后面的“续”的过程中进行读取:
• 当“上传(下载)的行为”出现中断,我们需要记录本次上传(下载)的位置(position)。
• 当“续”这一行为开始,我们直接跳转到postion处继续上传(下载)的行为。
在此有实例如下:(注意:此次进行的只不过是同一本地主机中不同磁盘之间的文件传输)
一:在E盘根目录中新建一文件test.txt,内容为abcdef如图:
保存后查看属性可知文件大小为6字节,因为只有6个英语字母,如图:
二:先来一次无断点的上传下载,其实只是将E盘作为上传者将文件上传至D盘
代码如下:
/**
* 在E盘建立一个文件【test.txt】并将其复制到D盘
* 本程序是将test.txt中的数据分成1字节(1B)进行传输,因为数据缓冲区设置的大小是1
*/
package test1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test1Point1 {
public static void main(String[] args) {
// 源文件与目标文件
File sourceFile = new File("E:/", "test.txt");///源文件目录以及名称
File targetFile = new File("D:/", "test1.txt");///目标文件夹已经复制品名称
// 输入输出流
FileInputStream fis = null;
FileOutputStream fos = null;
// 数据缓冲区
byte[] buf = new byte[1]; ///设置buf【缓冲区】的大小是1,代表我们每次
///read,是读取一个字节的数据(即1个英文字母);
try {
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
// 数据读写
while (fis.read(buf) != -1) {
System.out.println("数据读写中...");
fos.write(buf);
}
} catch (FileNotFoundException e) {
System.out.println("指定文件不存在");
} catch (IOException e) {
// TODO: handle exception
} finally {
try {
// 关闭输入输出流
if (fis != null)
fis.close();
if (fos != null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码运行后会发现在D盘的根目录下产生一个与E盘相同的文件tset.txt
三:接下来进行断点续传(注意,此次断点信号是人为产生,而且是文件传输进行一半时产生的断点信号),只需将代码进行稍微的修改即可:
/**
* 实现断点续传,与测试1.1对比
* E盘新建文件test.txt内容为abcdef
* 运行程序,打开D盘的tset.txt文件,发现只有abc,10秒后再次打开会发现文件传输全部完成
*/
package test1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**添加*/import java.io.RandomAccessFile;
public class Test1Point2 {
/**添加*/ private static int position = -1;//定义了一个变量position,记录在发生中断的时候,已完成读写的位置。
public static void main(String[] args) {
// 源文件与目标文件
File sourceFile = new File("E:/", "test.txt");
File targetFile = new File("D:/", "test.txt");
// 输入输出流
FileInputStream fis = null;
FileOutputStream fos = null;
// 数据缓冲区
byte[] buf = new byte[1];
try {
fis = new FileInputStream(sourceFile);
fos = new FileOutputStream(targetFile);
// 数据读写
while (fis.read(buf) != -1) {
fos.write(buf);
/**添加*/// 当已经上传了3字节的文件内容时,网络中断了,抛出异常
/**添加*/ if (targetFile.length() == 3) {
/**添加*/ position = 3;///模拟一个中断行为的发生
/**添加*/ throw new FileAccessException();
/**添加*/ }
}
} /**添加*/catch (FileAccessException e) {
/**添加*/keepGoing(sourceFile,targetFile, position);}
catch (FileNotFoundException e) {
System.out.println("指定文件不存在");
} catch (IOException e) {
// TODO: handle exception
} finally {
try {
// 关闭输入输出流
if (fis != null)
fis.close();
if (fos != null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**注释*//**keepGoing的具体实现*/
private static void keepGoing(File source,File target, int position) {
try {
Thread.sleep(10000);/**线程休息10秒,*/
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
RandomAccessFile readFile = new RandomAccessFile(source, "rw");
RandomAccessFile writeFile = new RandomAccessFile(target, "rw");
readFile.seek(position);
writeFile.seek(position);
// 数据缓冲区
byte[] buf = new byte[1];
// 数据读写
while (readFile.read(buf) != -1) {
writeFile.write(buf);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class FileAccessException extends Exception {
}
程序运行结果是D盘出现与E盘相同的文件test.txt但是内容只有一半,10秒钟后再次打开会发现文件已完整。