private long CheckFile(DownloadFileRangeState state) { long startPos = 0; if (File.Exists(state.TempPath)) { state.FileStream = File.OpenWrite(state.TempPath); startPos = state.FileStream.Length; state.FileStream.Seek(startPos, SeekOrigin.Current); } else { try { string direName = Path.GetDirectoryName(state.TempPath); if (!Directory.Exists(direName)) { Directory.CreateDirectory(direName); } state.FileStream = new FileStream(state.TempPath, FileMode.Create); } catch (Exception e) { state.Exception = e; startPos = -1; state.Close(); } } return(startPos); }
private void WriteFile(DownloadFileRangeState state, long startPos) { var bytesReceived = startPos; byte[] bytes = new byte[1024]; bool isDownloadCompleted = false; var totalBytesReceived = state.Respone.ContentLength + startPos; int readSize = state.Stream.Read(bytes, 0, 1024); while (readSize > 0 && state.IsRangeDownload) { if (state == null || state.FileStream == null) { break; } lock (state.FileStream) { if (DownloadProgressChangedEx != null) { DownloadProgressChangedEx(this, new DownloadProgressChangedEventArgsEx(bytesReceived, totalBytesReceived, ((float)bytesReceived / totalBytesReceived), state.UserState)); } state.FileStream.Write(bytes, 0, readSize); bytesReceived += readSize; if (totalBytesReceived != 0 && bytesReceived >= totalBytesReceived) { try { state.Close(); if (File.Exists(state.Path)) { File.Delete(state.Path); } File.Move(state.TempPath, state.Path); isDownloadCompleted = true; state.Done(isDownloadCompleted); } catch (Exception e) { state.Exception = e; state.Done(false); } } else { readSize = state.Stream.Read(bytes, 0, 1024); } } } if (!isDownloadCompleted) { state.Exception = new Exception("Request for early closure"); } }
public void DownloadFileRange(string url, string path, object userState) { if (_state != null && _state.IsRangeDownload) { return; } _state = new DownloadFileRangeState(path, userState, this); _state.OnCompleted = () => DownloadFileCompletedEx; _state.IsRangeDownload = true; long startPos = CheckFile(_state); if (startPos == -1) { return; } try { _state.Request = (HttpWebRequest)GetWebRequest(new Uri(url)); _state.Request.ReadWriteTimeout = _timeOut; _state.Request.Timeout = _timeOut; _state.Respone = _state.Request.GetResponse(); _state.Stream = _state.Respone.GetResponseStream(); if (_state.Respone.ContentLength == startPos) { _state.Close(); File.Move(_state.TempPath, _state.Path); _state.Done(true); return; } if (startPos > 0) { _state.Request.AddRange((int)startPos); } long totalBytesReceived = _state.Respone.ContentLength + startPos; long bytesReceived = startPos; if (totalBytesReceived != 0 && bytesReceived >= totalBytesReceived) { _state.Close(); try { if (File.Exists(_state.Path)) { File.Delete(_state.Path); } File.Move(_state.TempPath, _state.Path); } catch (Exception e) { _state.Exception = e; _state.Close(); } } else { WriteFile(_state, startPos); } } catch (Exception e) { _state.Exception = e; throw new Exception($"'DownloadFileRange' This function has an internal exception : { e.Message } .", e.InnerException); } finally { if (_state != null) { _state.Close(); } } }