public async Task UploadCrazy(string localFile, string remoteFileDirectory, int blockLength = 1) { TransmissionHelper transmissionHelper = new TransmissionHelper(); transmissionHelper.OnProgressHandler += (timeCost, plannedSpeed, downloadSpeed) => { this.OnProgressHandler?.Invoke(timeCost, plannedSpeed, downloadSpeed); }; try { if (!File.Exists(localFile)) { throw new WebDAVException($"{localFile} is not file."); } FileInfo fileInfo = new FileInfo(localFile); using (Stream stream = File.OpenRead(localFile)) { transmissionHelper.SetTotalLength(fileInfo.Length); List <Task> tasks = new List <Task>(); long step = (1L << 20) * blockLength; // 2^10 * 2^10 == 1MB var blockCount = Math.Ceiling(fileInfo.Length * 1.0 / step); string id = Guid.NewGuid().ToString("N"); transmissionHelper.Start(); Console.WriteLine($"Start upload ! total length{fileInfo.Length}"); for (int i = 0; i < blockCount; i++) { long start = i * step; long end = (i + 1) * step - 1; if ((fileInfo.Length - 1) < end) { end = fileInfo.Length - 1; } int stepStream = (int)(end - start + 1); byte[] buffer = new byte[stepStream]; stream.Seek(start, SeekOrigin.Begin); await stream.ReadAsync(buffer, 0, stepStream); tasks.Add(UploadPartial(transmissionHelper, new MemoryStream(buffer), remoteFileDirectory, start, end, stream.Length)); } await Task.Run(() => Task.WaitAll(tasks.ToArray())); } transmissionHelper.Stop(); Console.WriteLine($"End uplaod ! Enjoy yourself !"); } catch (Exception ex) { transmissionHelper.Stop(); throw ex; } }
private async Task DownloadPartial(string id, TransmissionHelper transmissionHelper, string remoteFilePath, long startBytes, long endBytes, long step) { var headers = new Dictionary <string, string> { { "translate", "f" }, { "Range", "bytes=" + startBytes + "-" + endBytes } }; if (CustomHeaders != null) { foreach (var keyValuePair in CustomHeaders) { headers.Add(keyValuePair.Key, keyValuePair.Value); } } using (FileStream file = new FileStream($"{id}.dat", FileMode.Create)) using (var stream = await DownloadFile(remoteFilePath, headers)) { var length = endBytes - startBytes + 1; var consumed = 0; var buffer = new byte[step]; while (consumed < length) { var read = await stream.ReadAsync(buffer, 0, buffer.Length); await file.WriteAsync(buffer, 0, read); consumed += read; transmissionHelper.IncreaseRealTimeLength(read); } } }
private async Task UploadPartial(TransmissionHelper transmissionHelper, Stream content, string remoteFileName, long startBytes, long endBytes, long totalLength) { Console.WriteLine($"startBytes:{startBytes} endBytes:{endBytes}"); // Should not have a trailing slash. var uploadUri = await GetServerUrl(remoteFileName, false).ConfigureAwait(false); HttpResponseMessage response = null; try { Console.WriteLine("current stream length:" + content.Length); response = await HttpUploadRequest(uploadUri.Uri, HttpMethod.Put, content, null, startBytes, endBytes, totalLength).ConfigureAwait(false); if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.Created) { throw new WebDAVException((int)response.StatusCode, "Failed uploading file."); } if (response.IsSuccessStatusCode) { transmissionHelper.IncreaseRealTimeLength(endBytes - startBytes + 1); } } finally { if (response != null) { response.Dispose(); } content.Close(); } }
/// <summary> /// MutilateThread Download /// </summary> /// <param name="remoteFile">file url</param> /// <param name="localFileDirectory">local dic</param> /// <param name="blockLength">N MB</param> /// <returns></returns> public async Task DownloadCrazy(Item remoteFile, DirectoryInfo localFileDirectory, int blockLength = 1) { TransmissionHelper transmissionHelper = new TransmissionHelper(); transmissionHelper.OnProgressHandler += (timeCost, plannedSpeed, downloadSpeed) => { this.OnProgressHandler?.Invoke(timeCost, plannedSpeed, downloadSpeed); }; try { if (remoteFile == null || remoteFile.IsCollection || remoteFile.ContentLength == null) { throw new WebDAVException("remoteFile is nil or collection"); } long?contentLength = remoteFile.ContentLength.Value; if (contentLength == null) { throw new WebDAVException("Response content is nil"); } else { transmissionHelper.SetTotalLength(remoteFile.ContentLength.Value); } List <Task> tasks = new List <Task>(); long step = (1L << 20) * blockLength; // 2^10 * 2^10 == 1MB var blockCount = Math.Ceiling(remoteFile.ContentLength.Value * 1.0 / step); string id = Guid.NewGuid().ToString("N"); transmissionHelper.Start(); Console.WriteLine($"Start download ! total length{remoteFile.ContentLength.Value}"); for (int i = 0; i < blockCount; i++) { long start = i * step; long end = (i + 1) * step - 1; if ((remoteFile.ContentLength.Value - 1) < end) { end = remoteFile.ContentLength.Value - 1; } tasks.Add(DownloadPartial(id + i, transmissionHelper, remoteFile.Href, start, end, step)); } await Task.Run(() => Task.WaitAll(tasks.ToArray())); transmissionHelper.Stop(); Console.WriteLine("Files is merging ...."); using (FileStream fileOut = new FileStream(Path.Combine(localFileDirectory.FullName.TrimEnd('/') + "/" + remoteFile.DisplayName.TrimStart('/')), FileMode.Create)) { for (int i = 0; i < blockCount; i++) { using (FileStream fileStream = new FileStream($"{id + i}.dat", FileMode.Open)) { await fileStream.CopyToAsync(fileOut); } File.Delete($"{id + i}.dat"); Console.WriteLine($"{i} is OK"); } } Console.WriteLine($"End download ! Enjoy yourself !"); } catch (Exception ex) { transmissionHelper.Stop(); throw ex; } }