PowerShell
PowerShell
HTTP Download in Parallel with Simultaneous Range Requests
See more HTTP Examples
Demonstrates how to download a large file with parallel simultaneous requests, where each request downloads a segment (range) of the remote file.Chilkat PowerShell Downloads
Add-Type -Path "C:\chilkat\ChilkatDotNet47-x64\ChilkatDotNet47.dll"
$success = $false
# This requires the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.
$http = New-Object Chilkat.Http
# First get the size of the file to be downloaded.
$url = "https://www.chilkatsoft.com/hamlet.xml"
$resp = New-Object Chilkat.HttpResponse
$success = $http.HttpNoBody("HEAD",$url,$resp)
if ($success -eq $false) {
$($http.LastErrorText)
exit
}
$remoteFileSize = $resp.ContentLength
$("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 = New-Object Chilkat.Http
$http2 = New-Object Chilkat.Http
$http3 = New-Object Chilkat.Http
$http4 = New-Object Chilkat.Http
$sbRange = New-Object Chilkat.StringBuilder
$sbRange.SetString("bytes=<range-start>-<range-end>")
$numReplaced = $sbRange.ReplaceI("<range-start>",0)
$numReplaced = $sbRange.ReplaceI("<range-end>",$chunkSize - 1)
$($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)
$($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)
$($sbRange.GetAsString())
$http3.SetRequestHeader("Range",$sbRange.GetAsString())
$sbRange.SetString("bytes=<range-start>-")
$numReplaced = $sbRange.ReplaceI("<range-start>",3 * $chunkSize)
$($sbRange.GetAsString())
$http4.SetRequestHeader("Range",$sbRange.GetAsString())
# Start each range download
$task1 = $http1.DownloadAsync($url,"qa_output/chunk1.dat")
$task1.Run()
$task2 = $http2.DownloadAsync($url,"qa_output/chunk2.dat")
$task2.Run()
$task3 = $http3.DownloadAsync($url,"qa_output/chunk3.dat")
$task3.Run()
$task4 = $http4.DownloadAsync($url,"qa_output/chunk4.dat")
$task4.Run()
# Wait for the downloads to complete.
$numLive = 4
while ($numLive -gt 0) {
$numLive = 0
if ($task1.Live -eq $true) {
$numLive = $numLive + 1
}
if ($task2.Live -eq $true) {
$numLive = $numLive + 1
}
if ($task3.Live -eq $true) {
$numLive = $numLive + 1
}
if ($task4.Live -eq $true) {
$numLive = $numLive + 1
}
if ($numLive -gt 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() -eq $false) {
$($task1.ResultErrorText)
$numErrors = $numErrors + 1
}
if ($task2.GetResultBool() -eq $false) {
$($task2.ResultErrorText)
$numErrors = $numErrors + 1
}
if ($task3.GetResultBool() -eq $false) {
$($task3.ResultErrorText)
$numErrors = $numErrors + 1
}
if ($task4.GetResultBool() -eq $false) {
$($task4.ResultErrorText)
$numErrors = $numErrors + 1
}
if ($numErrors -gt 0) {
exit
}
# All downloads were successful.
# Compose the file from the parts.
$fac = New-Object Chilkat.FileAccess
$success = $fac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml")
if ($success -eq $false) {
$($fac.LastErrorText)
}
else {
$("Success.")
}
# 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")
$("bSame = " + $bSame)