await using var contentStream = await response.Content.ReadAsStreamAsync(ct); await using var fileStream = new FileStream( destinationFilePath, existingBytes > 0 ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 81920, useAsync: true);
public static class SonicDownloader
// 3️⃣ Stream download using var response = await _http.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead, ct); response.EnsureSuccessStatusCode(); sonic.exe download
// ------------------------------------------------------------- // Helper: get Content‑Length via HEAD request // ------------------------------------------------------------- private static async Task<long> GetContentLengthAsync(string url, CancellationToken ct) using var request = new HttpRequestMessage(HttpMethod.Head, url); using var response = await _http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, ct); response.EnsureSuccessStatusCode();
// 2️⃣ Prepare request (HEAD to get total size, optional resume) long totalBytes = await GetContentLengthAsync(downloadUrl, ct); long existingBytes = 0; await using var contentStream = await response
while ((read = await contentStream.ReadAsync(buffer.AsMemory(0, buffer.Length), ct)) > 0) await fileStream.WriteAsync(buffer.AsMemory(0, read), ct); totalRead += read; progress?.Report((totalRead, totalBytes));
var progress = new Progress<(long downloaded, long? total)>(p => if (p.total.HasValue) double percent = (double)p.downloaded / p.total.Value * 100; progressBar.Value = (int)percent; lblStatus.Text = $"Downloading… percent:F1% (p.downloaded / 1024:#,##0 KB)"; else lblStatus.Text = $"Downloading… p.downloaded / 1024:#,##0 KB"; ); 0 ? FileMode.Append : FileMode.Create
var buffer = new byte[81920]; long totalRead = existingBytes; int read;