private long DownloadChunkBlock(FileState state, short blockIndex) { Stream rsm = null; HttpWebResponse response = null; HttpWebRequest request = null; int errorCount = 0; retry: try { BlockState bs = state.GetBlock(blockIndex); if (bs == null || bs.Size <= 0) { return(-1); } Log.Debug("- DownloadChunkBlock index:{0}[{1}-{2}]", blockIndex, bs.EnterPoint, bs.UnTransmittedSize); if (bs.IsCompleted) { return(0); } using (var fs = File.Open(state.LocalFileUri.LocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) { Log.Debug("- Open file {0} successful!", state.LocalFileUri.LocalPath); fs.Seek(bs.EnterPoint, SeekOrigin.Begin); Log.Debug("- File seek({0}) successful!", bs.EnterPoint); int count = bs.UnTransmittedSize; request = DownloadRequst.GetWebRequest(state.RemoteFileUri, Parameter.Environment); request.Accept = "*/*"; request.AllowAutoRedirect = true; request.ProtocolVersion = HttpVersion.Version10; request.Timeout = Timeout.Infinite; //request.CookieContainer = CookieUtil.GetCokieContainer(state.RemoteFileInfo); if (state.BlockCount > 1) { request.AddRange(bs.EnterPoint); } for (int i = 0; i < request.Headers.Count; ++i) { Log.Debug("^ [{2}]{0}: {1}", request.Headers.Keys[i], request.Headers[i], blockIndex); } Log.Debug("- [{0}]请求开始", blockIndex); response = (HttpWebResponse)request.GetResponse(); Log.Debug("- [{0}]请求返回", blockIndex); const int buffersize = 64 * 1024; var buffer = new byte[buffersize]; rsm = response.GetResponseStream(); Log.Debug("- [{0}]开始接收数据!", blockIndex); bs.BlockRunState = ActionStateType.Running; while (count > 0) { if (bs.AssistThread == null) { Log.Debug("- AssistThread is null"); } if (bs.BlockRunState == ActionStateType.Stop) { Log.Info("- [{0}] Stoped,Address:{1}", blockIndex, bs.EnterPoint); break; } int ret = (rsm != null ? rsm.Read(buffer, 0, buffersize) : 0); if (ret <= 0) { Log.Debug("- Receive Data Error, 5 seconds retry!"); Thread.Sleep(5000); continue; } int retcopy = (count < ret ? count : ret); fs.Write(buffer, 0, retcopy); count -= retcopy; bs.TransmittedSize += retcopy; state.TransmittedLength += retcopy; if (count <= 0) { break; } } fs.Close(); } Log.Debug("- [{0}]数据接收完成!", blockIndex); } catch (WebException e) { Log.Info(e.ToString()); Log.Warn(e.Status.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { // state.SaveLogFile(); return(-1); } if (e.Status == WebExceptionStatus.ReceiveFailure) { errorCount++; if (errorCount <= 3) { Thread.Sleep(1000); Log.Info("goto retry {0} times by ReceiveFailure", errorCount); goto retry; } } if (e.Status == WebExceptionStatus.Timeout) { errorCount++; if (errorCount <= 5) { Thread.Sleep(1000); Log.Info("goto retry {0} times by Timeout: {1}", errorCount, e.InnerException.Message); goto retry; } } Log.Error(e); } catch (ThreadAbortException e) { Log.Warn(e.ToString()); } catch (Exception e) { Log.Info(e.ToString()); // state.SaveLogFile(); return(-1); } finally { if (rsm != null) { rsm.Close(); } if (response != null) { response.Close(); } if (request != null) { request.Abort(); } Log.Info("{0} block is finished!", blockIndex); // state.SaveLogFile(); } return(0); }
private void CreateDownload(TransferParameter parameter) { try { bool allowRanges = false; int contentLength; _request = DownloadRequst.GetWebRequest(parameter); _request.PreAuthenticate = true; _request.Accept = "*/*"; _request.AllowAutoRedirect = true; _request.Method = "HEAD"; Log.Debug("^ GET {0} HTTP/{1}", parameter.TransferUrl, _request.ProtocolVersion); Log.Debug("^ Host: {0}", _request.Address.Host); Log.Debug("^ Accept: {0}", _request.Accept); Log.Debug("^ User-Agent: {0}", _request.UserAgent); Log.Debug("^ Referer: {0}", _request.Referer); var response = (HttpWebResponse)_request.GetResponse(); if (response.ContentLength == -1 || response.ContentLength > 0x7fffffff) { contentLength = 1024 * 1024 * 5; } else { contentLength = (int)response.ContentLength; } Log.Debug("v HTTP/{0} {1} OK", response.ProtocolVersion, response.StatusCode); for (int i = 0; i < response.Headers.Count; ++i) { if (String.Compare(response.Headers.Keys[i], "Accept-Ranges", StringComparison.InvariantCultureIgnoreCase) == 0) { allowRanges = true; } Log.Debug("v {0}: {1}", response.Headers.Keys[i], response.Headers[i]); } response.Close(); lock (this) { FileUtil.CreateFile(parameter.LocalFile, contentLength); } DownloadFileState = new FileState(parameter.TransferUrl, parameter.LocalFile, contentLength, (allowRanges ? _chunkCount : (short)1)); AssignFileStateDelegate(); DownloadFileState.FireFileDownloadBeginingEvent(); } catch (WebException e) { Log.Warn("- Got an Excetpion {0} in Create WebException", e.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { string a = ((HttpWebResponse)e.Response).StatusCode.ToString(); a += ((HttpWebResponse)e.Response).StatusDescription; Log.Warn(a); } throw new WebException(e.Message); } catch (Exception e) { Log.Warn("- Got an Excetpion {0} in Create Exception", e.ToString()); throw new Exception(e.Message); } }
private void DownloadFile(TransferParameter parameter) { try { string logstr = "下载任务开始,正在创建临时目录."; Log.Debug(logstr); string[] tempList = Directory.GetDirectories(Logger.TemporaryDirectory); DirectoryInfo di = null; if (tempList.Length > 0) { foreach (string item in tempList) { di = new DirectoryInfo(item); if (di.LastWriteTime <= DateTime.Now.AddMonths(-6)) { FileUtil.DeleteDirectory(item); } } } logstr = "正在创建本地保存目录."; Log.Debug(logstr); string localDir = Path.GetDirectoryName(parameter.LocalFile); if (!string.IsNullOrEmpty(localDir)) { di = new DirectoryInfo(localDir); if (!di.Exists) { di.Create(); } } logstr = "正在初始化..."; Log.Debug(logstr + "\r\n" + parameter.ToString()); DownloadState.BlockList.Clear(); var currentApply = new Apply(); DownloadState.BlockList = DownloadRequst.GetBlocks(parameter, ref currentApply); Log.Debug(currentApply.ToString()); DownloadState.AllowAppend = false; DownloadState.StopDownload = false; DownloadState.HasFinished = false; DownloadState.IsCompleted = false; DownloadState.OutputDebugLog = true; BlockEvents.CompletedBytesCount = 0; BlockEvents.TotalBytes = currentApply.FileSize; ServicePointManager.DefaultConnectionLimit = 100; var historyApply = new Apply(); var historyFileItem = new FileItem(); var historyparameter = new TransferParameter(); if (DownloadHistory.Exists(parameter.RemoteFile, ref historyFileItem, ref historyApply, ref historyparameter, false) && DownloadState.CurrentApply.Equals(historyApply) && !File.Exists(parameter.LocalFile)) { logstr = "已恢复下载."; Log.Debug(logstr); DownloadState.AllowAppend = true; historyFileItem.HasBreaked = true; if (string.IsNullOrEmpty(historyFileItem.BreakInfo)) { historyFileItem.BreakInfo = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } else { historyFileItem.BreakInfo += ";" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } DownloadHistory.Update(parameter.RemoteFile, historyFileItem); } else if (DownloadHistory.Exists(parameter.RemoteFile, ref historyFileItem, ref historyApply, ref historyparameter, true) && parameter.Equals(historyparameter) && File.Exists(historyparameter.LocalFile)) { var fileInfo = new FileInfo(parameter.LocalFile); if (fileInfo.Length == DownloadState.CurrentApply.FileSize && fileInfo.LastWriteTime == DownloadState.CurrentApply.LastModified) { logstr = parameter.TransferUrl + "此前已完成下载."; Log.Debug(logstr); DownloadState.HasFinished = true; BlockEvents.CompletedBytesCount = fileInfo.Length; BlockEvents.OnProgress(100, 100); BlockEvents.OnCompleted(); return; } } if (!DownloadState.AllowAppend && !DownloadState.HasFinished) { DownloadHistory.Insert(parameter.RemoteFile); logstr = "已将本次下载任务追加到历史."; Log.Debug(logstr); } if (BlockEvents.Begining != null) { BlockEvents.Begining(parameter.LocalFile); } logstr = "开始处理分块"; Log.Warn(logstr); foreach (Blocks item in DownloadState.BlockList) { item.ReStore(); item.Download(); logstr += item.ToString() + "\r\n"; Log.Debug(logstr); } Log.Info("文件下载完毕"); } catch (Exception err) { BlockEvents.OnException(err); } }