Untitled

mail@pastecode.io avatar
unknown
csharp
2 years ago
2.5 kB
3
Indexable
Never
/// <summary>
        /// Downloads a file from the specified URL and saves it to the specified path, under
        /// the name of the url after formatting.
        /// </summary>
        /// <param name="url">The URL to download the file from</param>
        /// <param name="directory">The directory to download the files into</param>
        /// <param name="loading">The ProgressBar to update with the download progress</param> 
        public static async Task DownloadModpack(string url, string directory, ProgressBar loading)
        {
            string filename = RequestHandler.FormatUrlToFilename(url) + ".download";
            string parentDirectory = InternalFileManager.INSTANCE.QueryDirectoryPath(directory, true);

            Logging.INSTANCE.LogAll($@"Requesting modpack content...");
            loading.Value = 5; // Aesthetics
            
            // Get the file content in a stream from the URL, as well as the response, and open a FileStream to write into.
            using (HttpResponseMessage response = await ClientInstance.GetAsync(url, HttpCompletionOption.ResponseContentRead))
            using (Stream contentStream = await response.Content.ReadAsStreamAsync())
            using (FileStream fileStream = File.Create(Path.Combine(parentDirectory, filename)))
            {
                byte[] buffer = new byte[1024 * 3072];  // Sets the buffer (Amount of bytes read per iteration)
                
                // Request the file size in bytes
                long.TryParse(response.Content.Headers.First(h => h.Key.Equals("Content-Length")).Value.First(), out long contentSize);
                Logging.INSTANCE.LogAll("File size: " + contentSize + " bytes", "DOWNLOADER");
                while (true)
                {
                    // Reads a chunk of bytes from the contentStream
                    var byteChunk = await contentStream.ReadAsync(buffer, 0, buffer.Length);
                    
                    // Write the chunk to the file and update the loading bar
                    await fileStream.WriteAsync(buffer, 0, byteChunk);
                    int percentageDownloaded = (int)(fileStream.Length / (double)contentSize * 100.0D);
                    loading.Value = percentageDownloaded > 5 ? percentageDownloaded : 5;
                    loading.Text = $@"Downloading... {loading.Value}%";
                    
                    if (byteChunk == 0) break; // If the chunk is empty, break.
                }
            }