async Task ReadPartialRemoteStream( HttpResponseMessage response, Stream localStream, long existingLength, int threadNumber, long contentLength) { int byteSize = 0; long totalReceived = byteSize + existingLength, nowReceived = 0; byte[] buffer = new byte[bufflength]; #if (NETCOREAPP) using (Stream remoteStream = await response.Content.ReadAsStreamAsync()) #else using (Stream remoteStream = await response.Content.ReadAsStreamAsync()) #endif { var sw = Stopwatch.StartNew(); while ((byteSize = await remoteStream.ReadAsync(buffer, 0, buffer.Length, downloadPartialToken)) > 0) { downloadPartialToken.ThrowIfCancellationRequested(); localStream.Write(buffer, 0, byteSize); totalReceived += byteSize; nowReceived += byteSize; segmentDownloadProperties[threadNumber] = new SegmentDownloadProperties(totalReceived, nowReceived, contentLength, sw.Elapsed.TotalSeconds) { CurrentReceived = byteSize }; } sw.Stop(); } }
public async Task <bool> GetPartialSessionStream(SegmentDownloadProperties j) { Stream stream; try { string partialOutput = string.Format("{0}.{1:000}", downloadPartialOutputPath, j.PartRange + 1); FileInfo fileinfo = new FileInfo(partialOutput); #if DEBUG Console.WriteLine($"\tPart {j.PartRange + 1} > Start: {j.StartRange}{(j.StartRange == 0 ? "\t" : "")}\tEnd: {j.EndRange}\tSize: {BpUtility.ToBytesCount(j.EndRange - j.StartRange)}"); #endif long existingLength = fileinfo.Exists ? fileinfo.Length : 0; long fileSize = (j.EndRange - j.StartRange) + 1; if (existingLength > fileSize) { fileinfo.Create(); } if (existingLength != fileSize) { using (HttpClient client = new HttpClient()) { HttpRequestMessage request = new HttpRequestMessage() { RequestUri = new Uri(downloadPartialInputPath) }; request.Headers.TryAddWithoutValidation("User-Agent", App.UserAgent); request.Headers.Range = new RangeHeaderValue(j.StartRange + existingLength, j.EndRange); HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, downloadPartialToken); using (stream = fileinfo.Open(FileMode.Append, FileAccess.Write)) { try { await ReadPartialRemoteStream(response, stream, existingLength, j.PartRange, j.EndRange - j.StartRange); } catch (OperationCanceledException) { stream.Dispose(); throw new OperationCanceledException(); } } } } else if (existingLength == fileSize) { segmentDownloadProperties[j.PartRange] = new SegmentDownloadProperties(fileSize, 0, fileSize, new TimeSpan().TotalSeconds) { CurrentReceived = 0 }; } } catch (OperationCanceledException) { #if DEBUG Console.WriteLine($"Download cancelled for part {j.PartRange + 1}"); #endif return(true); } catch (Exception ex) { #if DEBUG Console.WriteLine($"{ex}"); #endif return(false); } return(true); }