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
(Swift 2) 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.
func chilkatTest() { // This requires the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. let http = CkoHttp() var success: Bool // First get the size of the file to be downloaded. var url: String? = "https://www.chilkatsoft.com/hamlet.xml" var resp: CkoHttpResponse? = http.GetHead(url) if http.LastMethodSuccess == false { print("\(http.LastErrorText)") return } var remoteFileSize: Int = resp!.ContentLength resp = nil print("Downloading \(remoteFileSize) bytes...") // Let's download in 4 chunks. // (the last chunk will be whatever remains after the 1st 3 equal sized chunks) var chunkSize: Int = 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.. let http1 = CkoHttp() let http2 = CkoHttp() let http3 = CkoHttp() let http4 = CkoHttp() let sbRange = CkoStringBuilder() sbRange.SetString("bytes=<range-start>-<range-end>") var numReplaced: Int = sbRange.ReplaceI("<range-start>", replacement: 0).intValue numReplaced = sbRange.ReplaceI("<range-end>", replacement: chunkSize - 1).intValue print("\(sbRange.GetAsString())") http1.SetRequestHeader("Range", value: sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-<range-end>") numReplaced = sbRange.ReplaceI("<range-start>", replacement: chunkSize).intValue numReplaced = sbRange.ReplaceI("<range-end>", replacement: 2 * chunkSize - 1).intValue print("\(sbRange.GetAsString())") http2.SetRequestHeader("Range", value: sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-<range-end>") numReplaced = sbRange.ReplaceI("<range-start>", replacement: 2 * chunkSize).intValue numReplaced = sbRange.ReplaceI("<range-end>", replacement: 3 * chunkSize - 1).intValue print("\(sbRange.GetAsString())") http3.SetRequestHeader("Range", value: sbRange.GetAsString()) sbRange.SetString("bytes=<range-start>-") numReplaced = sbRange.ReplaceI("<range-start>", replacement: 3 * chunkSize).intValue print("\(sbRange.GetAsString())") http4.SetRequestHeader("Range", value: sbRange.GetAsString()) // Start each range download var task1: CkoTask? = http1.DownloadAsync(url, saveToPath: "qa_output/chunk1.dat") task1!.Run() var task2: CkoTask? = http2.DownloadAsync(url, saveToPath: "qa_output/chunk2.dat") task2!.Run() var task3: CkoTask? = http3.DownloadAsync(url, saveToPath: "qa_output/chunk3.dat") task3!.Run() var task4: CkoTask? = http4.DownloadAsync(url, saveToPath: "qa_output/chunk4.dat") task4!.Run() // Wait for the downloads to complete. var numLive: Int = 4 while 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. var numErrors: Int = 0 if task1!.GetResultBool() == false { print("\(task1!.ResultErrorText)") numErrors = numErrors + 1 } if task2!.GetResultBool() == false { print("\(task2!.ResultErrorText)") numErrors = numErrors + 1 } if task3!.GetResultBool() == false { print("\(task3!.ResultErrorText)") numErrors = numErrors + 1 } if task4!.GetResultBool() == false { print("\(task4!.ResultErrorText)") numErrors = numErrors + 1 } if numErrors > 0 { task1 = nil task2 = nil task3 = nil task4 = nil return } // All downloads were successful. // Compose the file from the parts. let fac = CkoFileAccess() success = fac.ReassembleFile("qa_output", partPrefix: "chunk", partExtension: "dat", reassembledFilename: "qa_output/hamlet.xml") if success == false { print("\(fac.LastErrorText)") } else { print("Success.") } task1 = nil task2 = nil task3 = nil task4 = nil // Let's download in the regular way, and then compare files.. success = http.Download(url, saveToPath: "qa_output/hamletRegular.xml") // Compare files. var bSame: Bool = fac.FileContentsEqual("qa_output/hamlet.xml", path2: "qa_output/hamletRegular.xml") print("bSame = \(bSame)") } |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.