断点续传要做的是:前一次读写行为如果出现中断,请记录下此次读写完成的文件内容的位置信息;当续传开始则直接将指针移至此处,开始继续读写操作。
两个重要步骤:1.先是记录position 2.当续传的行为开始,我们需要从上次记录的position位置开始读写操作,所以我们需要一个类似于指针功能的东西。
java已经为我们提供了这样的一个类,那就是RandomAccessFile。这个类的功能从名字上就很直观的体现了,能够随机的去访问文件。
API文件中是这样说明该类的:
此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型byte数组。如果随机访问文件以读取/写入模式创建,则输入操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐函数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过getFilePointer方式读取,并通过seek方法设置。
demo:
public static void main(String[] args) {
File readFile = new File("E:\\randomAccessFile.txt");
File writeFile = new File("F:\\randomAccessFile.txt");
int position = -1;
byte[] buffer = new byte[1];
try (FileInputStream fis = new FileInputStream(readFile);
FileOutputStream fos = new FileOutputStream(writeFile)) {
while (fis.read(buffer) != -1) {
System.out.println("write data...");
fos.write(buffer);
if (writeFile.length() == 3) {
System.out.println("网络断了...");
position = 3;
throw new FileAccessException();
}
}
} catch (FileAccessException e) {
keepGoing(readFile, writeFile, position);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void keepGoing(File source, File target, int position) {
try {
Thread.sleep(10000);
} 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) {
System.out.println("续传中...");
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 {}