コード例 #1
0
        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);
        }
コード例 #2
0
 private void CreateOrRestoreSliceList()
 {
     // 分片文件存在,则从该文件中还原分片信息
     if (File.Exists(SliceFileName))
     {
         SliceList = SliceHelper.RestoreSliceList(SliceFileName);
         return;
     }
     // 新建分片
     SliceList = SliceHelper.CreateSliceList(from.size, MinSliceSize);
     //保存一次新创建的分片列表
     SliceHelper.SaveSliceList(SliceFileName, SliceList);
 }
コード例 #3
0
        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);
        }
コード例 #4
0
 private void Flush()
 {
     if (cache.TotalSize > 0)
     {
         lock (cache)
         {
             if (cache.TotalSize > 0)
             {
                 cache.Flush();
                 cache.Reset();
                 SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据
             }
         }
     }
 }
コード例 #5
0
        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);
        }
コード例 #6
0
 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));
 }
コード例 #7
0
 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));
 }
コード例 #8
0
        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);
        }