/// <summary> /// Report progress /// </summary> /// <param name="progress"></param> private void ReportProgress(DownloadProgess progress) { this.TotalBytesRead = progress.TotalBytesDownloaded; this.PercentCompleted = progress.Percent; if (this.Status != progress.DownloadStatus) { this.Status = progress.DownloadStatus; } this.DownloadSpeedBytesPerSecond = progress.DownloadSpeedBytesPerSecond; if (!networkSpeedInitialized) { this.InitializeNetworkSpeedPlot(); } this.UpdateNetworkSpeedPlot(); }
/// <summary> /// Download file async /// </summary> /// <param name="url">The url</param> /// <param name="targetPath">The target path</param> /// <param name="progress">Progess changed handler</param> /// <param name="token">The cancellation tocken.</param> /// <returns></returns> public async Task DownloadFileAsync(Uri url, string localFile, IProgress <DownloadProgess> progress, CancellationToken cancellationToken) { int bytesRead = default(int); long totalBytesRead = default(long); double percent = default(double); Stopwatch sw = new Stopwatch(); long start = default(long); try { // Check local dir this.CheckTargetDir(Path.GetDirectoryName(localFile)); // Get file size from server long fileSize = await GetFileSizeAsync(url); FtpWebRequest request = this.CreateFtpWebRequest(url, WebRequestMethods.Ftp.DownloadFile); using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync()) { sw.Start(); start = sw.ElapsedMilliseconds; Stream data = response.GetResponseStream(); System.Diagnostics.Debug.WriteLine($"Downloading {url.AbsoluteUri} to {localFile}..."); byte[] byteBuffer = new byte[8 * 1024]; using (FileStream output = new FileStream(localFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 8 * 1024, useAsync: true)) { if (File.Exists(localFile)) { var fi = new FileInfo(localFile); totalBytesRead = fi.Length; } do { bytesRead = await data.ReadAsync(byteBuffer, 0, byteBuffer.Length); if (bytesRead > 0) { // Report progress totalBytesRead += bytesRead; if (totalBytesRead > 0) { if (progress != null) { if (sw.ElapsedMilliseconds - start >= uiUpdateIntervall) { start = sw.ElapsedMilliseconds; DownloadProgess args = new DownloadProgess(); args.DownloadStatus = DownloadStatus.Transferring; args.Percent = (totalBytesRead <= 0) ? default(double) : ((double)totalBytesRead / (double)fileSize); args.TotalBytesDownloaded = totalBytesRead; progress.Report(args); } } } await output.WriteAsync(byteBuffer, 0, bytesRead, cancellationToken); } }while (bytesRead > 0); } sw.Stop(); sw.Reset(); progress.Report(new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, DownloadStatus = DownloadStatus.Finished }); System.Diagnostics.Debug.WriteLine($"Downloaded {url.AbsoluteUri} to {localFile}"); } } catch (OperationCanceledException) { System.Diagnostics.Debug.WriteLine("Download cancelled!"); progress.Report(new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, DownloadStatus = DownloadStatus.Stopped }); } catch (WebException e) { progress.Report(new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, DownloadStatus = DownloadStatus.Failed }); System.Diagnostics.Debug.WriteLine($"Failed to download {url.AbsoluteUri} to {localFile}"); System.Diagnostics.Debug.WriteLine(e); throw; } finally { sw.Stop(); sw.Reset(); } }
/// <summary> /// Download file /// </summary> /// <param name="url">The url</param> /// <param name="targetPath">The target path</param> /// <param name="progress">Progess changed handler</param> /// <param name="token">The cancellation token.</param> /// <returns></returns> public void DownloadFile(Uri url, string localFile, IProgress <DownloadProgess> progress, CancellationToken cancelToken) { int bytesRead = default(int); long totalBytesRead = default(long); double percent = default(double); long fileSize = default(long); Stopwatch sw = new Stopwatch(); long lastUpdatedTime = default(long); long lastUpdateDownloadedSize = default(long); try { // Check local dir this.CheckTargetDir(Path.GetDirectoryName(localFile)); // Get file size from server fileSize = GetFileSize(url); FtpWebRequest request = this.CreateFtpWebRequest(url, WebRequestMethods.Ftp.DownloadFile); using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) { sw.Start(); lastUpdatedTime = sw.ElapsedMilliseconds; using (Stream data = response.GetResponseStream()) { System.Diagnostics.Debug.WriteLine($"Downloading {url.AbsoluteUri} to {localFile}..."); byte[] byteBuffer = new byte[8 * 1024]; using (FileStream output = new FileStream(localFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 8 * 1024, useAsync: true)) { totalBytesRead = output.Length; do { bytesRead = data.Read(byteBuffer, 0, byteBuffer.Length); if (bytesRead > 0) { totalBytesRead += bytesRead; if (progress != null) { // Report progress if (sw.ElapsedMilliseconds - lastUpdatedTime >= uiUpdateIntervall) { //System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: Updated UI"); DownloadProgess args = new DownloadProgess(); args.DownloadStatus = DownloadStatus.Transferring; args.Percent = (totalBytesRead <= 0) ? default(double) : ((double)totalBytesRead / (double)fileSize); args.TotalBytesDownloaded = totalBytesRead; args.ElapsedTime = sw.Elapsed; // Calculate speed (Bytes per Second) long sizeDiff = totalBytesRead - lastUpdateDownloadedSize; lastUpdateDownloadedSize = totalBytesRead; args.DownloadSpeedBytesPerSecond = sizeDiff / TimeSpan.FromMilliseconds(sw.ElapsedMilliseconds - lastUpdatedTime).Seconds; // Set last updated time lastUpdatedTime = sw.ElapsedMilliseconds; // Report progress progress.Report(args); } } output.Write(byteBuffer, 0, bytesRead); } }while (bytesRead > 0 && !cancelToken.IsCancellationRequested); } sw.Stop(); var downloadProgress = new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, ElapsedTime = sw.Elapsed }; if (cancelToken.IsCancellationRequested) { downloadProgress.DownloadStatus = DownloadStatus.Cancelled; } else { downloadProgress.DownloadStatus = DownloadStatus.Finished; this.OnFileDownloadCompleted(new FileDownloadCompletedEventArgs(url, new FileInfo(localFile))); } progress.Report(downloadProgress); System.Diagnostics.Debug.WriteLine($"Downloaded {url.AbsoluteUri} to {localFile}"); } } } catch (OperationCanceledException) { System.Diagnostics.Debug.WriteLine("Download cancelled!"); progress.Report(new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, DownloadStatus = DownloadStatus.Stopped }); } catch (WebException e) { progress.Report(new DownloadProgess() { Percent = percent, TotalBytesDownloaded = totalBytesRead, DownloadStatus = DownloadStatus.Failed }); System.Diagnostics.Debug.WriteLine($"Failed to download {url.AbsoluteUri} to {localFile}"); System.Diagnostics.Debug.WriteLine(e); //throw; } finally { sw.Stop(); sw.Reset(); } }