加了断点续传,但是测试大文件时报错了,尚未定位到问题

This commit is contained in:
free will committed 2020-11-06 17:31:53 +08:00
1 parent 048c56a636
commit 87959dd679
9 files changed
+413 -25

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
#commit changes
#Fri Nov 06 17:19:27 CST 2020
filePoint-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=B8BBF8A24FA481E4A861C3CC610F57A6
fileServerPath-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=24B14C90089CD398802AD5610E3E6A22
fileName-2879941E9BB27B30BDC1235CC3B80CEC5A66153C5D117A18A129A9A40C9EA4453B8ADC1001EB791D6763A5CC72B5B58F5E712434666FE889F569CC44E05BC68B38CEA774067E8FA17346D5A1B2771B0551C8881DC90A978ED404134D87D5D2433F3ECCBFDDCF07C7C959369553543F441169D7A23CFFA50F69DAE85ECCBFACCB854776C82E54FDFF19B63213373583184C5AC3F61F7E4CD78AABA4D7CF794866A887F99432A67B81A86D2456E023720707366C175BEA530CC13DEA961E62244C821549B5C7730F20BD93429070CDD1C61A2165A39268318A742AA9B109B3A3BE6DDB36C4352D2F738188EFFDE41B6123=3B35BD05A292F4C18EFE1F8C5AC312F349DF5188BBA8183ED8C96ED7CB946855EF95C39E8B8C29DEFCC82B690256C74F
+9
View File
@@ -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
+2 -2
View File
@@ -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
@@ -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);