private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object userdata) { Slice slice = (Slice)userdata; if (slice.tid != Interlocked.Read(ref taskId))//本次任务被取消 { lock (locker) { if (IsCancelled) { slice.status = SliceStatus.Cancelled; } else { slice.status = SliceStatus.Failed; } } return(0); } long size = data.Length; if (size > slice.totalSize - slice.doneSize) { size = slice.totalSize - slice.doneSize; } if (size > 0) { try { bigfile.Update(slice.start + slice.doneSize, data, 0, (int)size); } catch (Exception ex) { throw; } } slice.doneSize += size; lock (locker) DoneSize += size; if (slice.doneSize == slice.totalSize) //分片已经下载完成 { slice.status = SliceStatus.Successed; size = 0; } lock (sliceFileLocker) SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据 long downloadedSize = 0; lock (locker) downloadedSize = DoneSize; ProgressEventArgs args = new ProgressEventArgs(downloadedSize, from.size); fireProgress(args); if (args.Cancel) { slice.status = SliceStatus.Cancelled; return(0); } return((uint)size); }
private void CreateOrRestoreSliceList() { // 分片文件存在,则从该文件中还原分片信息 if (File.Exists(SliceFileName)) { SliceList = SliceHelper.RestoreSliceList(SliceFileName); return; } // 新建分片 SliceList = SliceHelper.CreateSliceList(from.size, MinSliceSize); //保存一次新创建的分片列表 SliceHelper.SaveSliceList(SliceFileName, SliceList); }
private void CreateOrRestoreSliceList() { // 分片文件存在,则从该文件中还原分片信息 if (File.Exists(SliceFileName)) { SliceList = SliceHelper.RestoreSliceList(SliceFileName); return; } long slizeSize = SliceHelper.CalculateSliceSize(fromFileInfo.Length, MIN_SLICE_SIZE, MAX_SLICE_COUNT); // 新建分片 SliceList = SliceHelper.CreateSliceList(fromFileInfo.Length, (int)slizeSize); //保存一次新创建的分片列表 SliceHelper.SaveSliceList(SliceFileName, SliceList); }
private void Flush() { if (cache.TotalSize > 0) { lock (cache) { if (cache.TotalSize > 0) { cache.Flush(); cache.Reset(); SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据 } } } }
private void uploadTask(object objTID) { long tid = (long)objTID; try { BaiduPCS pcs; Slice slice; PcsFileInfo rf; pcs = this.pcs.clone(); while (tid == Interlocked.Read(ref taskId)) { slice = popSlice(); if (slice == null) { break; } slice.tid = tid; pcs.WriteUserData = slice; rf = pcs.upload_slicefile(new OnReadBlockFunction(Read), slice, (uint)slice.totalSize); if (!string.IsNullOrEmpty(rf.md5)) { slice.md5 = rf.md5; slice.status = SliceStatus.Successed; } else if (slice.status == SliceStatus.Cancelled) { Cancel(); } else { slice.status = SliceStatus.Failed; lock (locker) Error = new Exception(pcs.getError()); StopAllDownloadThreads(); } lock (sliceFileLocker) SliceHelper.SaveSliceList(SliceFileName, SliceList); } } catch (Exception ex) { lock (locker) Error = ex; StopAllDownloadThreads(); } Interlocked.Decrement(ref runningThreadCount); }
public override void Download() { if (Downloading) { throw new Exception("Can't download, since the previous download is not complete."); } DoneSize = 0; Success = false; IsCancelled = false; Error = null; Downloading = true; SliceFileName = null; SliceList = null; bigfile = null; try { SliceFileName = "download-" + from.md5 + ".slice"; SliceFileName = Path.Combine(Path.Combine(WorkFolder, pcs.getUID()), SliceFileName); StateFileNameDecideEventArgs args = new StateFileNameDecideEventArgs() { SliceFileName = SliceFileName }; fireStateFileNameDecide(args); SliceFileName = args.SliceFileName; CreateOrRestoreSliceList(); // 创建或还原分片列表 CreateDirectory(to); //创建目录 CreateLocalFile(); // 如果需要则创建本地文件 bigfile = new BigFileHelper(to, from.size); //映射文件到内存 foreach (Slice slice in SliceList) { if (slice.status != SliceStatus.Successed) { slice.status = SliceStatus.Pending; //重新下载未成功的分片 slice.doneSize = 0; } else { DoneSize += slice.doneSize; } } DownloadSliceList(); // 启动线程来下载分片 Wait(); // 等待所有线程退出 CheckResult(); // 检查下载结果 } catch (Exception ex) { Success = false; IsCancelled = false; Error = ex; } if (bigfile != null) { bigfile.Dispose(); bigfile = null; } if (Success) { SliceHelper.DeleteSliceFile(SliceFileName); } Downloading = false; fireCompleted(new CompletedEventArgs(Success, IsCancelled, Error)); }
public override void Upload() { if (Uploading) { throw new Exception("Can't upload, since the previous upload is not complete."); } DoneSize = 0; Success = false; IsCancelled = false; Error = null; Uploading = true; SliceFileName = null; SliceList = null; fromFileInfo = null; try { BaiduPCS pcs = this.pcs.clone(); string key; if (string.IsNullOrEmpty(FileMD5)) { string validate_md5, validate2_md5; fromFileInfo = new FileInfo(from); if (!pcs.md5(from, 0, MIN_SLICE_SIZE, out validate_md5)) { throw new Exception("Can't calculate md5 for " + from + "."); } if (!pcs.md5(from, fromFileInfo.Length - MIN_SLICE_SIZE, MIN_SLICE_SIZE, out validate2_md5)) { throw new Exception("Can't calculate md5 for " + from + "."); } key = from + " => " + to + ", size=" + fromFileInfo.Length.ToString() + ", validate1_md5=" + validate_md5 + ", validate2_md5=" + validate2_md5; key = Utils.md5(key.ToLower()); } else { key = FileMD5; } SliceFileName = "upload-" + key + ".slice"; SliceFileName = Path.Combine(WorkFolder, pcs.getUID(), SliceFileName); StateFileNameDecideEventArgs args = new StateFileNameDecideEventArgs() { SliceFileName = SliceFileName }; fireStateFileNameDecide(args); SliceFileName = args.SliceFileName; CreateOrRestoreSliceList(); // 创建或还原分片列表 foreach (Slice slice in SliceList) { if (slice.status != SliceStatus.Successed) { slice.status = SliceStatus.Pending; //重新上传未成功的分片 slice.doneSize = 0; } else { DoneSize += slice.doneSize; } } UploadSliceList(); // 启动线程来下载分片 Wait(); // 等待所有线程退出 List <string> md5list = new List <string>(); if (CheckResult(md5list)) // 检查下载结果 { Result = pcs.create_superfile(to, md5list.ToArray(), IsOverWrite); if (!Result.IsEmpty) { Success = true; IsCancelled = false; } else { Success = false; IsCancelled = false; Error = new Exception(pcs.getError()); } } else { Success = false; } } catch (Exception ex) { Success = false; IsCancelled = false; Error = ex; } if (Success) { SliceHelper.DeleteSliceFile(SliceFileName); } Uploading = false; fireCompleted(new CompletedEventArgs(Success, IsCancelled, Error)); }
private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object userdata) { Slice slice = (Slice)userdata; try { if (slice.tid != Interlocked.Read(ref taskId))//本次任务被取消 { lock (locker) { if (IsCancelled) { slice.status = SliceStatus.Cancelled; } else { slice.status = SliceStatus.Failed; } } return(0); } long size = data.Length; if (size > slice.totalSize - slice.doneSize) { size = slice.totalSize - slice.doneSize; } if (size > 0) { lock (cache) cache.Add(slice.start + slice.doneSize, data, (int)size); } slice.doneSize += size; lock (locker) DoneSize += size; if (slice.doneSize == slice.totalSize) //分片已经下载完成 { slice.status = SliceStatus.Successed; size = 0; } lock (cache) { if (cache.TotalSize >= AppSettings.MaxCacheSize * 1024) { cache.Flush(); cache.Reset(); SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据 } } long downloadedSize = 0; lock (locker) downloadedSize = DoneSize; ProgressEventArgs args = new ProgressEventArgs(downloadedSize, from.size); fireProgress(args); if (args.Cancel) { slice.status = SliceStatus.Cancelled; lock (locker) Error = new Exception("Cancelled"); return(0); } return((uint)size); } catch (Exception ex) { lock (locker) Error = ex; slice.status = SliceStatus.Error; } return(0); }