mirror of
https://gitee.com/willfree/minbrowser.git
synced 2026-10-05 01:15:42 +08:00
加了断点续传,但是测试大文件时报错了,尚未定位到问题
This commit is contained in:
1 parent
048c56a636
commit
87959dd679
9 files changed
+413
-25
No files matched your search
@@ -0,0 +1,5 @@
|
||||
#commit changes
|
||||
#Fri Nov 06 17:19:27 CST 2020
|
||||
filePoint-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=B8BBF8A24FA481E4A861C3CC610F57A6
|
||||
fileServerPath-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=24B14C90089CD398802AD5610E3E6A22
|
||||
fileName-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=3B35BD05A292F4C18EFE1F8C5AC312F349DF5188BBA8183ED8C96ED7CB946855EF95C39E8B8C29DEFCC82B690256C74F
|
||||
@@ -20,3 +20,12 @@
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/20200822-%E5%91%A8%E6%8A%A5-%E5%88%98%E6%B6%9B.pptx 文件操作:下载 文件耗时:525ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/ppov%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95-8.21(1).docx 文件操作:下载 文件耗时:263ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/20200822-%E5%91%A8%E6%8A%A5-%E5%88%98%E6%B6%9B.pptx 文件操作:下载 文件耗时:433ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/%E5%91%A8%E6%8A%A5-%E9%98%99%E5%BB%BA%E6%98%8E-2020.08.22.pdf 文件操作:下载 文件耗时:581ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/%E8%82%96%E6%8C%AF%E5%A8%81%E5%91%A8%E6%8A%A5-20200821.pptx 文件操作:下载 文件耗时:723ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/%E8%82%96%E6%8C%AF%E5%A8%81%E5%91%A8%E6%8A%A5-20200821.pptx 文件操作:下载 文件耗时:342ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/%E5%90%B4%E6%94%BF%E7%90%AA%E5%91%A8%E6%8A%A5-20200821(1).pptx 文件操作:下载 文件耗时:9323ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/upupoo%E5%8D%95%E6%9C%BA%E7%89%8820200119.exe 文件操作:下载 文件耗时:30741ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/upupoo%E5%8D%95%E6%9C%BA%E7%89%8820200119.exe 文件操作:下载 文件耗时:73358ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/%E9%9F%A6%E5%9B%BD%E5%8D%8E%E5%91%A8%E6%8A%A5-20200822.pptx 文件操作:下载 文件耗时:388ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/upupoo%E5%8D%95%E6%9C%BA%E7%89%8820200119.exe 文件操作:下载 文件耗时:34951ms
|
||||
文件名:/MIN/Nginx/test2/%E5%8C%97%E4%BA%AC%E5%A4%A7%E5%AD%A6/%E4%BF%A1%E6%81%AF%E5%B7%A5%E7%A8%8B%E5%AD%A6%E9%99%A2/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%BA%94%E7%94%A8%E6%8A%80%E6%9C%AF/A218/upupoo%E5%8D%95%E6%9C%BA%E7%89%8820200119.exe 文件操作:下载 文件耗时:11545ms
|
||||
@@ -1,6 +1,6 @@
|
||||
#\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6
|
||||
#Sun Nov 01 18:58:43 CST 2020
|
||||
ServerIPAddress=121.15.171.92
|
||||
#Fri Nov 06 15:29:27 CST 2020
|
||||
ServerIPAddress=192.168.25.25
|
||||
MIS_PORT=6363
|
||||
DataPackagePrefix=/MIN/Nginx/test2
|
||||
ServerPortAddress=6363
|
||||
|
||||
+101
-5
@@ -1,10 +1,7 @@
|
||||
package cn.minbrowser.MiniMinData.FileTransfer;
|
||||
|
||||
import cn.minbrowser.MiniMinData.KeyManager;
|
||||
import cn.minbrowser.MiniMinData.util.FacePool;
|
||||
import cn.minbrowser.MiniMinData.util.FileLengthUtil;
|
||||
import cn.minbrowser.MiniMinData.util.FilePathUtil;
|
||||
import cn.minbrowser.MiniMinData.util.OrderIPrefixUtil;
|
||||
import cn.minbrowser.MiniMinData.util.*;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
@@ -63,6 +60,15 @@ public class DownLoadClientBasedFacePool {
|
||||
private AtomicBoolean isCancelFileTransferFlag=new AtomicBoolean(false);
|
||||
private Integer sliceSize;
|
||||
|
||||
// 断点续传:此偏移量/序号之前的文件部分已经全部传输成功
|
||||
private AtomicLong successPoint=new AtomicLong(1);
|
||||
// 断点续传:point及其之后的兴趣包,已经传输成功的兴趣包序号
|
||||
private Map<Long, Boolean> successList = new ConcurrentHashMap<>();
|
||||
// 断点续传:当前文件哈希值/其它可以唯一标识该文件的String
|
||||
private String fileHashString;
|
||||
// 是否开启断点续传
|
||||
private boolean BPRswitch=true;
|
||||
|
||||
/**
|
||||
* 文件传输构造器
|
||||
* @param filename 要下载的文件在linux上的相对路径
|
||||
@@ -85,6 +91,7 @@ public class DownLoadClientBasedFacePool {
|
||||
this.facePool=new FacePool(facepoolnumber);
|
||||
this.facePool.start(minServerIpString,minServerPortInteger);
|
||||
System.out.println("***********FacePool中并发数:"+facepoolnumber+"***********");
|
||||
fileHashString=filename+"_"+sliceNumber;
|
||||
// 先初始化一个本地文件
|
||||
try {
|
||||
String localName= FilePathUtil.getPureFileNameFromLinux(filename);
|
||||
@@ -95,6 +102,65 @@ public class DownLoadClientBasedFacePool {
|
||||
}
|
||||
}
|
||||
|
||||
/** 断点续传:
|
||||
* 传入一个刚被后台成功响应的兴趣包序号,
|
||||
* 判断[point,current]之间的兴趣包序号是否全部被成功响应
|
||||
*/
|
||||
private boolean isAllOK(Long point,Long currentNo){
|
||||
for(Long i=point;i<=currentNo;i++){
|
||||
if(!successList.containsKey(i)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 断点续传:
|
||||
* 移除successList中已经成功发送的部分,减少内存占用
|
||||
*/
|
||||
private void mvSuccessNum(Long fromNo,Long toNo){
|
||||
for(Long i=fromNo;i<=toNo;i++){
|
||||
successList.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
/** 断点续传:
|
||||
* 对每个成功收到200应答的兴趣包执行如下程序,以维持断点续传的功能
|
||||
* @param sliceNo
|
||||
*/
|
||||
private void refreshSuccessPoint(Long sliceNo){
|
||||
// 当前断点
|
||||
Long point=successPoint.get();
|
||||
// 加入successList
|
||||
successList.put(sliceNo,true);
|
||||
// 如果当前断点到新收到数据包之间的兴趣包全部成功响应,
|
||||
// 更新断点,并清理内存
|
||||
if(isAllOK(point,sliceNo)){
|
||||
successPoint.getAndSet(sliceNo+1);
|
||||
mvSuccessNum(point,sliceNo);
|
||||
}
|
||||
}
|
||||
|
||||
/** 断点续传:
|
||||
* 将本次传输的断点信息保存到本地
|
||||
*/
|
||||
public void setPointInfo(){
|
||||
String fileName=FilePathUtil.getPureFileNameFromLinux(filename);
|
||||
FileBPRUtil.setUploadBreakPointInfo(
|
||||
fileHashString,fileName,localDir,successPoint.get());
|
||||
System.out.println("保存断点信息成功!!!");
|
||||
}
|
||||
|
||||
/** 断点续传:
|
||||
* 移除已经上传成功的文件断点信息
|
||||
*/
|
||||
private void rmPointInfo(){
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)){
|
||||
FileBPRUtil.deleteUploadBreakPointInfo(fileHashString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否含有超时次数超过阈值的
|
||||
* @return
|
||||
@@ -136,10 +202,31 @@ public class DownLoadClientBasedFacePool {
|
||||
* @return
|
||||
*/
|
||||
public boolean downloadData() {
|
||||
|
||||
// flag: 标志传输结束状态。0-尚未传输,1-全部传输完成;2-主动中断下载;3-网络状况不佳
|
||||
Integer transferFlag=0;
|
||||
|
||||
/**
|
||||
* 断点续传:判断是否有断点续传记录
|
||||
*/
|
||||
if(FileBPRUtil.isHaveUploadBreakPointInfo(fileHashString)&&BPRswitch){
|
||||
// 有记录,则判断文件名和服务器地址是否一致
|
||||
FileBPRUtil.BPRInfo bprInfo=FileBPRUtil.getUploadBreakPointInfo(fileHashString);
|
||||
String fileName=FilePathUtil.getPureFileNameFromLinux(filename);
|
||||
if((!(bprInfo==null))
|
||||
&&bprInfo.getFileName().equals(fileName)
|
||||
&&bprInfo.getFileLocator().equals(localDir)){
|
||||
// 都一致,则更新recvCount\currentOffset\successPoint
|
||||
System.out.println("即将开始断点续传...");
|
||||
recvCount.getAndSet(bprInfo.getPoint());
|
||||
currentSliceNo=(int)recvCount.get();
|
||||
successPoint.getAndSet(bprInfo.getPoint());
|
||||
}else{
|
||||
System.out.println("即将开始文件下载...");
|
||||
}
|
||||
}else {
|
||||
System.out.println("即将开始文件下载...");
|
||||
}
|
||||
|
||||
while (true) {
|
||||
//判断是否已经上传安成
|
||||
if (recvCount.longValue()>=this.sliceNumber) {
|
||||
@@ -206,8 +293,14 @@ public class DownLoadClientBasedFacePool {
|
||||
}
|
||||
// 如果文件传输正常完成,就返回true
|
||||
if(transferFlag==1){
|
||||
if(BPRswitch){
|
||||
rmPointInfo();
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
if(BPRswitch){
|
||||
setPointInfo();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -288,6 +381,9 @@ public class DownLoadClientBasedFacePool {
|
||||
// System.out.println("interest: "+interest.getName().toString());
|
||||
// System.out.println("data: "+data.getContent().toString());
|
||||
System.out.println("写入文件数据分片完毕:" + localDir + localName);
|
||||
if(BPRswitch){
|
||||
refreshSuccessPoint((long) sliceNo);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
|
||||
@@ -2,9 +2,9 @@ package cn.minbrowser.MiniMinData.util;
|
||||
|
||||
import net.named_data.jndn.Face;
|
||||
import net.named_data.jndn.encoding.EncodingException;
|
||||
import net.named_data.jndn.transport.UdpTransport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@@ -18,36 +18,43 @@ public class FacePool {
|
||||
// 采用阻塞队列来记录任务
|
||||
private LinkedBlockingQueue<Face> faceLinkedBlockingQueue;
|
||||
|
||||
private ArrayList<Face> faces;
|
||||
|
||||
private ExecutorService processEventThreadPool;
|
||||
private ExecutorService faceDealThreadPool;
|
||||
|
||||
public FacePool(int poolSize) {
|
||||
this.poolSize = poolSize;
|
||||
faces = new ArrayList<>();
|
||||
processEventThreadPool = Executors.newFixedThreadPool(poolSize);
|
||||
faceDealThreadPool = Executors.newFixedThreadPool(poolSize);
|
||||
faceLinkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
public FacePool start(String host, int port) {
|
||||
public FacePool start(String host, int port, boolean udp) {
|
||||
for (int i = 0; i < poolSize; i++) {
|
||||
faces.add(new Face(host, port));
|
||||
final int finalI = i;
|
||||
ProcessEventTask processEventTask = new ProcessEventTask(host, port, faces.get(i), i, task -> {
|
||||
Face face;
|
||||
if (udp) {
|
||||
face = new Face(new UdpTransport(), new UdpTransport.ConnectionInfo(host, port));
|
||||
System.out.println("use udp");
|
||||
} else {
|
||||
System.out.println("use tcp");
|
||||
face = new Face(host, port);
|
||||
}
|
||||
ProcessEventTask processEventTask = new ProcessEventTask(host, port, face, i, task -> {
|
||||
// 发生错误则自动重新创建face,建立连接,然后将processEvent任务提交到线程池当中
|
||||
processEventThreadPool.submit(task);
|
||||
faces.set(finalI, task.getFace());
|
||||
faceLinkedBlockingQueue.add(task.getFace());
|
||||
});
|
||||
processEventThreadPool.submit(processEventTask);
|
||||
|
||||
// 初始时Face池里所有的Face都是可用的
|
||||
faceLinkedBlockingQueue.add(faces.get(i));
|
||||
faceLinkedBlockingQueue.add(face);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FacePool start(String host, int port) {
|
||||
return start(host, port, false);
|
||||
}
|
||||
|
||||
public FacePool submit(AsyncUseFaceCallback asyncUseFaceCallback) {
|
||||
faceDealThreadPool.submit(() -> {
|
||||
try {
|
||||
@@ -139,15 +146,13 @@ public class FacePool {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// System.out.println("faceId: " + id + "(host: " + host + ", port: " + port + ") -> start");
|
||||
try {
|
||||
while (true) {
|
||||
face.processEvents();
|
||||
// System.out.println("faceId: " + id + " -> processEvent");
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} catch (IOException | EncodingException | InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
this.face = new Face(this.host, this.port);
|
||||
if (this.statusCallback != null) {
|
||||
this.statusCallback.onError(this);
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
package cn.minbrowser.MiniMinData.util;
|
||||
|
||||
import cn.minbrowser.util.Encryption.EncryptionUtil;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
|
||||
// 文件断点续传支持类
|
||||
// 功能:存储和移除传输失败的文件信息
|
||||
public class FileBPRUtil {
|
||||
|
||||
public static String fileBPRDir="." + File.separator + "min" + File.separator + "FileBPRenewal.properties";
|
||||
|
||||
// 判断某md5哈希值是否在本地存储条目中
|
||||
public static boolean isHaveUploadBreakPointInfo(String hashString) {
|
||||
// 加密
|
||||
hashString=EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(fileBPRDir));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
return false;
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
String filename=settingProperties.getProperty("fileName-"+hashString);
|
||||
System.out.println(hashString+" : "+filename);
|
||||
if(filename==null){
|
||||
return false;
|
||||
}else{
|
||||
System.out.println("本地存在该文件的断点信息:"+hashString);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public static boolean isHaveDownloadBreakPointInfo(String fileUrlString) {
|
||||
// return isHaveUploadBreakPointInfo(fileUrlString);
|
||||
// }
|
||||
|
||||
|
||||
// 存储上传文件断点信息到本地
|
||||
public static void setUploadBreakPointInfo(String hashString,
|
||||
String pureFileName,
|
||||
String serverPath,
|
||||
Long point){
|
||||
// 加密
|
||||
hashString=EncryptionUtil.encryptBasedAES(hashString);
|
||||
pureFileName=EncryptionUtil.encryptBasedAES(pureFileName);
|
||||
serverPath=EncryptionUtil.encryptBasedAES(serverPath);
|
||||
String pointString=EncryptionUtil.encryptBasedAES(point.toString());
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(fileBPRDir));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.setProperty("fileName-"+hashString, pureFileName);
|
||||
settingProperties.setProperty("fileServerPath-"+hashString,serverPath);
|
||||
settingProperties.setProperty("filePoint-"+hashString, pointString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(fileBPRDir));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移除上传文件的断点信息
|
||||
public static void deleteUploadBreakPointInfo(String hashString){
|
||||
// 加密
|
||||
hashString=EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(fileBPRDir));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
settingProperties.remove("fileName-"+hashString);
|
||||
settingProperties.remove("fileServerPath-"+hashString);
|
||||
settingProperties.remove("filePoint-"+hashString);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(fileBPRDir));
|
||||
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
|
||||
settingProperties.store(bw,"commit changes");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public static void setDownloadBreakPointInfo(String fileUrlString,
|
||||
// String pureFileName,
|
||||
// String localPath,
|
||||
// Long point){
|
||||
// setUploadBreakPointInfo(fileUrlString,pureFileName,localPath,point);
|
||||
// }
|
||||
//
|
||||
// public static void deleteDownloadBreakPointInfo(String fileUrlString){
|
||||
// deleteUploadBreakPointInfo(fileUrlString);
|
||||
// }
|
||||
|
||||
// 取出上传文件断点信息到本地
|
||||
public static BPRInfo getUploadBreakPointInfo(String hashString) {
|
||||
// 加密
|
||||
hashString=EncryptionUtil.encryptBasedAES(hashString);
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(fileBPRDir));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到断点续传配置文件...");
|
||||
}
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(bf);
|
||||
BPRInfo bprInfo=new BPRInfo();
|
||||
bprInfo.setFileId(hashString);
|
||||
bprInfo.setFileName(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("fileName-"+hashString)));
|
||||
bprInfo.setFileLocator(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("fileServerPath-"+hashString)));
|
||||
bprInfo.setPoint(Long.parseLong(EncryptionUtil.decryptBasedAES(settingProperties.getProperty("filePoint-"+hashString))));
|
||||
System.out.println("util-文件名:"+bprInfo.getFileName());
|
||||
System.out.println("util-文件断点:"+bprInfo.getPoint());
|
||||
System.out.println("util-文件路径:"+bprInfo.getFileLocator());
|
||||
if((bprInfo.getFileName()==null)||(bprInfo.getPoint()==null)||(bprInfo.getFileLocator()==null)){
|
||||
return null;
|
||||
}
|
||||
return bprInfo;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class BPRInfo {
|
||||
|
||||
// 文件唯一标识:上传中指的是哈希值,下载中指的是文件服务器URL
|
||||
// 现在上传和下载的该数值全部定义为:纯文件名_文件长度
|
||||
private String fileId;
|
||||
// 文件名称
|
||||
private String fileName;
|
||||
// 文件位置:上传中指的是文件服务器位置,下载中指的是文件本地位置
|
||||
private String fileLocator;
|
||||
// 断点续传位置
|
||||
private Long point;
|
||||
|
||||
public BPRInfo(){
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public void setFileId(String fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getFileLocator() {
|
||||
return fileLocator;
|
||||
}
|
||||
|
||||
public void setFileLocator(String fileLocator) {
|
||||
this.fileLocator = fileLocator;
|
||||
}
|
||||
|
||||
public Long getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public void setPoint(Long point) {
|
||||
this.point = point;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//1. 上传文件
|
||||
// 1.1 如果上传成功,且该次上传是续传,则移除该文件哈希值对应的本地存储条目;
|
||||
// 1.2 如果上传失败,则将文件断点信息存到本地:md5哈希值、纯文件名、服务器路径、断点
|
||||
// 1.3 每次上传文件,都要计算一下md5哈希值,然后查表,看本地有没有这个哈希值。
|
||||
// 如果有,就取文件名、要传的服务器路径,对比一下,全部都对的上,就从断点位置继续传该文件;如果没该哈希值,或文件名、路径不一致,则从0开始上传。
|
||||
//
|
||||
//2. 下载文件
|
||||
// 2.1 如果下载成功,且该次下载是续传,则移除该次下载的文件对应的服务器url所对应的本地存储条目;
|
||||
// 2.2 如果下载失败,则将文件断点信息保存到本地:文件对应的服务器url(如:/a/b.txt)、纯文件名、本地目录、断点
|
||||
// 2.3 每次下载文件,都查看要下载的文件的服务器url是否在本地存储中。如果在,就取纯文件名、本地目录对比一下,如果全部都对的上,就从断点位置继续传该文件;如果没该服务器url,或文件名、路径不一致,则从0开始下载。
|
||||
//3. 问题:
|
||||
// 1. 由于上述断点全部存储在客户端,那么对于电脑突然死机或用户直接关闭客户端的情况,是无法将断点信息保存到本地的,也就无法续传;
|
||||
// 2. 上述下载中,所谓文件服务器URL,并不是文件唯一标识,如果出现文件错判,续传之后的文件将可能是两个不同文件的结合体。
|
||||
|
||||
@@ -56,6 +56,8 @@ public class FileTransferProgressBarUtil {
|
||||
Task copyWorker;
|
||||
// 进度监听线程
|
||||
private Thread listenThread;
|
||||
// 进度条监听线程是否已经开始监听/被创建
|
||||
private boolean isThreadListenning=false;
|
||||
// 下载文件进度条stage
|
||||
private Stage downloadFileDialogStage;
|
||||
// 文件下载类
|
||||
@@ -222,9 +224,10 @@ public class FileTransferProgressBarUtil {
|
||||
downLoadClientBasedFacePool.cancelFileTransfer();
|
||||
// 关闭该次传输
|
||||
downLoadClientBasedFacePool.closeSelf();
|
||||
// 关闭进度条监听线程:再new一下是为了避免线程还没被创建
|
||||
listenThread =new Thread();
|
||||
listenThread.interrupt();
|
||||
// 关闭进度条监听线程
|
||||
if(isThreadListenning){
|
||||
listenThread.interrupt();
|
||||
}
|
||||
// 弹窗关闭
|
||||
downloadFileDialogStage.close();
|
||||
}
|
||||
@@ -288,6 +291,7 @@ public class FileTransferProgressBarUtil {
|
||||
}
|
||||
}
|
||||
});
|
||||
isThreadListenning=true;
|
||||
listenThread.start();
|
||||
// 开始下载文件
|
||||
boolean res = downLoadClientBasedFacePool.downloadData();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cn.minbrowser.util;
|
||||
// 生成配置文件
|
||||
|
||||
import cn.minbrowser.MiniMinData.util.FileBPRUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
@@ -12,6 +14,7 @@ public class GenerateSettingFiles {
|
||||
generateUserHomeNDNDir();
|
||||
generateFilecacheDir();
|
||||
generateSettingFile();
|
||||
generateBPRFile();
|
||||
// 如果配置文件中有信息缺失,提示用户补全信息后重启APP
|
||||
if(!SettingPropertyUtil.isAllSetting()){
|
||||
System.out.println("配置信息不全,请补全后重启APP");
|
||||
@@ -83,7 +86,7 @@ public class GenerateSettingFiles {
|
||||
}
|
||||
|
||||
public static void generateBPRFile() {
|
||||
String path = "." + File.separator + "min" + File.separator + "FileBPRenewal.properties";
|
||||
String path = FileBPRUtil.fileBPRDir;
|
||||
generateBPRFiles(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ public class NavigationBarController implements Initializable {
|
||||
this.userPhoto.setImage(new Image("file:resources/images/user.png"));
|
||||
this.settingPhoto.setImage(new Image("file:resources/images/3dot.png"));
|
||||
// 设置tabpane中tab的最大宽度
|
||||
tabPane.setTabMinWidth(tabHeaderWidth);
|
||||
tabPane.setTabMaxWidth(tabHeaderWidth);
|
||||
// 加载标签
|
||||
iniTab();
|
||||
@@ -74,7 +75,7 @@ public class NavigationBarController implements Initializable {
|
||||
*/
|
||||
private void iniTab(){
|
||||
tabPane.getTabs().add(new MiniTab(this));
|
||||
AnchorPane.setLeftAnchor(addTabButton,175D);
|
||||
AnchorPane.setLeftAnchor(addTabButton,tabHeaderWidth+24D);
|
||||
addTabButton.setOnAction((event) -> {
|
||||
MiniTab mt = new MiniTab(this);
|
||||
tabPane.getTabs().add(mt);
|
||||
|
||||
Reference in new issue
Block a user