断点续传实现:
简单来说应该分为两个角度来看待:
1、将要续传的文件
2、续传的文件
一、将要续传的文件
先说说将要续传的文件,既然是续传,那么肯定要有个标识,举例说明一下:
事先准备一个文件,大小是1852字节,第一次读取该文件的io流(0-1024字节),并将1024作为下次读取的首值,存储1024这个变量,就是在这个过程中的标识(记录所读到的位置) ,通过这个标识,我们下次读取的字节范围应该就是(1024-1852)字节。
要完成这个需求,应该考虑二个角度,
1)、这个标识放在那里,(我之后举得列子是放在持久化map[concurrenthashmap])
2)、既然是续传,那么肯定需要一个结束的状态的标识,来告诉续传的文件,我已经执行完了。
下面是关键代码:
(1),concurrenthashmap
concurrenthashmap的优点:
concurrenthashmap允许一边更新、一边遍历,也就是说在iterator对象遍历的时候,
concurrenthashmap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化,也就是说在iterator对象遍历的时候,concurrenthashmap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化。
简单来说:它只对put,remove操作使用了同步操作,get操作并不影响
代码如下:
package ga.gaapi.config;
import java.util.map;
import java.util.concurrent.concurrenthashmap;
public class zjhashmap {
static map conmap = new concurrenthashmap<>();
//新增
public static void addmap(string key,long value){
conmap.put(key,value);
}
//删除
public static void delect(string key){
conmap.remove(key);
}
//获取
public static long get(string key){
return conmap.get(key);
}
}
(2)、读取文件部分核心代码:
path :路径,
filename:文件名。
try{
file file = new file(path "\\" filename);
randomaccessfile raf = new randomaccessfile(file,"r");
long count = file.length();
byte[] read = new byte[integer.parseint(size)];
int len =0;
long fy = 0;
long flag = 1;
//判断标识中是否有值,有值的话,作为读取的首值
if (null!= zjhashmap.get(filename)){
raf.seek(zjhashmap.get(filename));
//计算要分页的数量,用来判断是否已经全部读取
fy = postutils.fy(count-zjhashmap.get(filename), long.parselong(size));
}else{
//计算要分页的数量,用来判断是否已经全部读取
fy = postutils.fy(count, long.parselong(size));
}
while((len=raf.read(read))!=-1){
bytearrayoutputstream outputstream = new bytearrayoutputstream();
outputstream.write(read,0,len);
outputstream.flush();
//读取的字节
byte[] bytes = outputstream.tobytearray();
//把字节数发送给续传文件方
//当前字节数目
zjhashmap.addmap(filename,raf.getfilepointer());
if (flag == fy){
//表示已到结尾,可以将这部分逻辑发送给续传文件方,告诉它已续传完毕
}
flag ;
outputstream.close();
}
raf.close();
zjhashmap.delect(filename);
}catch (exception e){
}
二、续传的文件
续传的文件就好说了,只要给一个续传的标识位置,和对应的字节流就可以了,代码如下:
filepath:生成的文件,用来续传用
content:将要写入的字节
position:续传的字节位置
randomaccessfile raf = null;
try {
raf = new randomaccessfile(filepath, "rw"); //将随机存取文件流连接到文件,访问方式设置为可读可写
raf.seek(position); //指定插入的位置
raf.write(content); //插入指定内容
} catch (ioexception e) {
e.printstacktrace();
} finally {
//关闭随机存取文件流
try {
raf.close();
} catch (ioexception e) {
e.printstacktrace();
}
}