Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Go) HTTP Download in Parallel with Simultaneous Range RequestsDemonstrates how to download a large file with parallel simultaneous requests, where each request downloads a segment (range) of the remote file.
// This requires the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. http := chilkat.NewHttp() var success bool // First get the size of the file to be downloaded. url := "https://www.chilkatsoft.com/hamlet.xml" resp := http.GetHead(url) if http.LastMethodSuccess() == false { fmt.Println(http.LastErrorText()) http.DisposeHttp() return } remoteFileSize := resp.ContentLength() resp.DisposeHttpResponse() fmt.Println("Downloading ", remoteFileSize, " bytes...") // Let's download in 4 chunks. // (the last chunk will be whatever remains after the 1st 3 equal sized chunks) chunkSize := remoteFileSize / 4 // The Range header is used to download a range from a resource // Range: bytes=<range-start>-<range-end> // or // Range: bytes=<range-start>- // We're writing code this way for clarity.. http1 := chilkat.NewHttp() http2 := chilkat.NewHttp() http3 := chilkat.NewHttp() http4 := chilkat.NewHttp() sbRange := chilkat.NewStringBuilder() sbRange.SetString("bytes=<range-start>-<range-end>") numReplaced := sbRange.ReplaceI("<range-start>",0) numReplaced = sbRange.ReplaceI("<range-end>",chunkSize - 1) fmt.Println(*sbRange.GetAsString()) http1.SetRequestHeader("Range",*sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-<range-end>") numReplaced = sbRange.ReplaceI("<range-start>",chunkSize) numReplaced = sbRange.ReplaceI("<range-end>",2 * chunkSize - 1) fmt.Println(*sbRange.GetAsString()) http2.SetRequestHeader("Range",*sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-<range-end>") numReplaced = sbRange.ReplaceI("<range-start>",2 * chunkSize) numReplaced = sbRange.ReplaceI("<range-end>",3 * chunkSize - 1) fmt.Println(*sbRange.GetAsString()) http3.SetRequestHeader("Range",*sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-") numReplaced = sbRange.ReplaceI("<range-start>",3 * chunkSize) fmt.Println(*sbRange.GetAsString()) http4.SetRequestHeader("Range",*sbRange.GetAsString()) // Start each range download c := make(chan *chilkat.Task) go http1.DownloadAsync(url,"qa_output/chunk1.dat",c) task1 := <-c c := make(chan *chilkat.Task) go http2.DownloadAsync(url,"qa_output/chunk2.dat",c) task2 := <-c c := make(chan *chilkat.Task) go http3.DownloadAsync(url,"qa_output/chunk3.dat",c) task3 := <-c c := make(chan *chilkat.Task) go http4.DownloadAsync(url,"qa_output/chunk4.dat",c) task4 := <-c // Wait for the downloads to complete. numLive := 4 for numLive > 0 { numLive = 0 if task1.Live() == true { numLive = numLive + 1 } if task2.Live() == true { numLive = numLive + 1 } if task3.Live() == true { numLive = numLive + 1 } if task4.Live() == true { numLive = numLive + 1 } if numLive > 0 { // SleepMs is a convenience method to cause the caller to sleep for N millisec. // It does not cause the given task to sleep.. task1.SleepMs(10) } } // All should be downloaded now.. // Examine the result of each Download. numErrors := 0 if task1.GetResultBool() == false { fmt.Println(task1.ResultErrorText()) numErrors = numErrors + 1 } if task2.GetResultBool() == false { fmt.Println(task2.ResultErrorText()) numErrors = numErrors + 1 } if task3.GetResultBool() == false { fmt.Println(task3.ResultErrorText()) numErrors = numErrors + 1 } if task4.GetResultBool() == false { fmt.Println(task4.ResultErrorText()) numErrors = numErrors + 1 } if numErrors > 0 { task1.DisposeTask() task2.DisposeTask() task3.DisposeTask() task4.DisposeTask() http.DisposeHttp() http1.DisposeHttp() http2.DisposeHttp() http3.DisposeHttp() http4.DisposeHttp() sbRange.DisposeStringBuilder() task1.DisposeTask() task2.DisposeTask() task3.DisposeTask() task4.DisposeTask() return } // All downloads were successful. // Compose the file from the parts. fac := chilkat.NewFileAccess() success = fac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml") if success == false { fmt.Println(fac.LastErrorText()) } else { fmt.Println("Success.") } task1.DisposeTask() task2.DisposeTask() task3.DisposeTask() task4.DisposeTask() // Let's download in the regular way, and then compare files.. success = http.Download(url,"qa_output/hamletRegular.xml") // Compare files. bSame := fac.FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml") fmt.Println("bSame = ", bSame) http.DisposeHttp() http1.DisposeHttp() http2.DisposeHttp() http3.DisposeHttp() http4.DisposeHttp() sbRange.DisposeStringBuilder() task1.DisposeTask() task2.DisposeTask() task3.DisposeTask() task4.DisposeTask() fac.DisposeFileAccess() |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.