public override FileTransferResponsed Handle(ContextRequest request, FileWriteHandleContext context) { FileTransferResponsed responsed = new FileTransferResponsed(request.FileRequest); var r = request.FileRequest; if (r.IsSendingOver)//在文件写入完成时,检查文件MD5 { if (request.ProgressDic.ContainsKey(r.FileMd5)) { request.ProgressDic[r.FileMd5].StateMsg = "校验中"; //request.ProgressDic.Remove(r.FileMd5); } #if DEBUG Console.WriteLine("Normal file send finished,prepare to check fileMD5"); #endif context.State = new StateFileExist();//检查文件长度是否相等或超过。PS:可能存在陷入无限死循环的隐患,调试时注意 return(context.Request(request)); } try { using (var fs = File.OpenWrite(request.WorkingPath)) { //在文件未传输完成时,持续写入文件 using (BinaryWriter bs = new BinaryWriter(fs)) { //Console.WriteLine($"seekoffset{r.SeekOffset},index={r.BlockIndex},length={r.BlockData.Length}"); bs.Seek((int)r.SeekOffset, SeekOrigin.Begin); bs.Write(r.BlockData); responsed.RemoteStreamPosition = fs.Position; } } var progress = request.ProgressDic[r.FileMd5]; progress.MaxValue = r.BlockCount; progress.ProgressValue = r.BlockIndex; progress.Title = r.FileName; progress.StateMsg = "传输中"; try { request?.ReceiveProgressHandler?.OnRecieving(r.FileMd5); //PubSubEvents.Singleton.Publish(new FileReceiveProgressChangedEvent() { ProgressMsg = request.ProgressDic[r.FileMd5] }); } catch { // ignored } } catch (Exception e) { #if DEBUG Console.WriteLine(e); #endif responsed.IsError = true; responsed.ErrMsg = e.Message; } return(responsed); }
public override FileTransferResponsed Handle(ContextRequest request, FileWriteHandleContext context) { long fsLength; FileTransferResponsed responsed; using (request.WorkingStream = File.Open(request.WorkingPath, FileMode.Open, FileAccess.ReadWrite)) { fsLength = request.WorkingStream.Length; if (fsLength > request.FileRequest.FileSize) { context.State = new StateFileLengthOutRange(); responsed = context.Request(request); } else if (fsLength == request.FileRequest.FileSize) { context.State = new StateFileLengthEqual(); responsed = context.Request(request); } else//文件实际长度既不大于也不等于远程端文件长度时 { context.State = new StateFileNormalTransfer();//若检查全部通过,则下一个状态是普通传输文件状态 if (fsLength >= request.FileRequest.EachBlockSize)//返回文件在倒数第2个Block时的offset,让远程端从该处发送对应Block数据,然后进入普通文件传输状态 { var fRequest = request.FileRequest; long position = ((fsLength / fRequest.EachBlockSize) - 1) * fRequest.EachBlockSize; responsed = new FileTransferResponsed(request.FileRequest); responsed.RemoteStreamPosition = position; } else//若文件长度小于区块长度,则直接按普通方式写入文件,此时远程SeekOffset应为0 { request.WorkingStream.Close();//防止正常写入文件时触发文件被占用异常 responsed = context.Request(request); } } } return(responsed);//保证FileStream被Using释放后才return }
public override FileTransferResponsed Handle(ContextRequest request, FileWriteHandleContext context) { var r = request.FileRequest; if (!request.ProgressDic.ContainsKey(r.FileMd5)) { var progress = new ProgressMessage(); request.ProgressDic.Add(r.FileMd5, progress); try { request?.ReceiveProgressHandler?.OnReceiveStart(r.FileMd5, progress); } catch { // ignored } } //若文件存在,则进入文件存在状态 if (File.Exists(request.WorkingPath)) { context.State = new StateFileExist(); return(context.Request(request)); } FileTransferResponsed responsed = new FileTransferResponsed(request.FileRequest); try { //创建文件并写入第一块数据 using (var fs = new FileStream(request.WorkingPath, FileMode.Create, FileAccess.Write)) { var data = request.FileRequest.BlockData; fs.Write(data, 0, data.Length); responsed.RemoteStreamPosition = fs.Position; } //TODO : 将Block的信息存起来,最好把每个Block的MD5值存起来,方便使用本地对比,而不是连接远程对比。或从远程下载BLock信息,再在本地读取,PS:内存也可。 } catch (Exception e) { #if DEBUG Console.WriteLine(e); #endif responsed.IsError = true; responsed.ErrMsg = e.Message; } context.State = new StateFileNormalTransfer(); return(responsed); }
public override FileTransferResponsed Handle(ContextRequest request, FileWriteHandleContext context) { //将文件削减至规定长度再重新进行MD5校验 var fs = request.WorkingStream; if (fs.CanWrite) { fs.SetLength(request.FileRequest.FileSize); fs.Flush(); context.State = new StateFileLengthEqual(); } else { throw new NotImplementedException("FileStream不允许写入"); } return(context.Request(request)); }