Visual FoxPro
Visual FoxPro
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 Visual FoxPro Downloads
LOCAL lnSuccess
LOCAL loHttp
LOCAL lcUrl
LOCAL loResp
LOCAL lnRemoteFileSize
LOCAL lnChunkSize
LOCAL loHttp1
LOCAL loHttp2
LOCAL loHttp3
LOCAL loHttp4
LOCAL loSbRange
LOCAL lnNumReplaced
LOCAL loTask1
LOCAL loTask2
LOCAL loTask3
LOCAL loTask4
LOCAL lnNumLive
LOCAL lnNumErrors
LOCAL loFac
LOCAL lnBSame
lnSuccess = 0
* This requires the Chilkat API to have been previously unlocked.
* See Global Unlock Sample for sample code.
loHttp = CreateObject('Chilkat.Http')
* First get the size of the file to be downloaded.
lcUrl = "https://www.chilkatsoft.com/hamlet.xml"
loResp = CreateObject('Chilkat.HttpResponse')
lnSuccess = loHttp.HttpNoBody("HEAD",lcUrl,loResp)
IF (lnSuccess = 0) THEN
? loHttp.LastErrorText
RELEASE loHttp
RELEASE loResp
CANCEL
ENDIF
lnRemoteFileSize = loResp.ContentLength
? "Downloading " + STR(lnRemoteFileSize) + " bytes..."
* Let's download in 4 chunks.
* (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
lnChunkSize = lnRemoteFileSize / 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..
loHttp1 = CreateObject('Chilkat.Http')
loHttp2 = CreateObject('Chilkat.Http')
loHttp3 = CreateObject('Chilkat.Http')
loHttp4 = CreateObject('Chilkat.Http')
loSbRange = CreateObject('Chilkat.StringBuilder')
loSbRange.SetString("bytes=<range-start>-<range-end>")
lnNumReplaced = loSbRange.ReplaceI("<range-start>",0)
lnNumReplaced = loSbRange.ReplaceI("<range-end>",lnChunkSize - 1)
? loSbRange.GetAsString()
loHttp1.SetRequestHeader("Range",loSbRange.GetAsString())
loSbRange.SetString("bytes=<range-start>-<range-end>")
lnNumReplaced = loSbRange.ReplaceI("<range-start>",lnChunkSize)
lnNumReplaced = loSbRange.ReplaceI("<range-end>",2 * lnChunkSize - 1)
? loSbRange.GetAsString()
loHttp2.SetRequestHeader("Range",loSbRange.GetAsString())
loSbRange.SetString("bytes=<range-start>-<range-end>")
lnNumReplaced = loSbRange.ReplaceI("<range-start>",2 * lnChunkSize)
lnNumReplaced = loSbRange.ReplaceI("<range-end>",3 * lnChunkSize - 1)
? loSbRange.GetAsString()
loHttp3.SetRequestHeader("Range",loSbRange.GetAsString())
loSbRange.SetString("bytes=<range-start>-")
lnNumReplaced = loSbRange.ReplaceI("<range-start>",3 * lnChunkSize)
? loSbRange.GetAsString()
loHttp4.SetRequestHeader("Range",loSbRange.GetAsString())
* Start each range download
loTask1 = loHttp1.DownloadAsync(lcUrl,"qa_output/chunk1.dat")
loTask1.Run()
loTask2 = loHttp2.DownloadAsync(lcUrl,"qa_output/chunk2.dat")
loTask2.Run()
loTask3 = loHttp3.DownloadAsync(lcUrl,"qa_output/chunk3.dat")
loTask3.Run()
loTask4 = loHttp4.DownloadAsync(lcUrl,"qa_output/chunk4.dat")
loTask4.Run()
* Wait for the downloads to complete.
lnNumLive = 4
DO WHILE lnNumLive > 0
lnNumLive = 0
IF (loTask1.Live = 1) THEN
lnNumLive = lnNumLive + 1
ENDIF
IF (loTask2.Live = 1) THEN
lnNumLive = lnNumLive + 1
ENDIF
IF (loTask3.Live = 1) THEN
lnNumLive = lnNumLive + 1
ENDIF
IF (loTask4.Live = 1) THEN
lnNumLive = lnNumLive + 1
ENDIF
IF (lnNumLive > 0) THEN
* SleepMs is a convenience method to cause the caller to sleep for N millisec.
* It does not cause the given task to sleep..
loTask1.SleepMs(10)
ENDIF
ENDDO
* All should be downloaded now..
* Examine the result of each Download.
lnNumErrors = 0
IF (loTask1.GetResultBool() = 0) THEN
? loTask1.ResultErrorText
lnNumErrors = lnNumErrors + 1
ENDIF
IF (loTask2.GetResultBool() = 0) THEN
? loTask2.ResultErrorText
lnNumErrors = lnNumErrors + 1
ENDIF
IF (loTask3.GetResultBool() = 0) THEN
? loTask3.ResultErrorText
lnNumErrors = lnNumErrors + 1
ENDIF
IF (loTask4.GetResultBool() = 0) THEN
? loTask4.ResultErrorText
lnNumErrors = lnNumErrors + 1
ENDIF
IF (lnNumErrors > 0) THEN
RELEASE loTask1
RELEASE loTask2
RELEASE loTask3
RELEASE loTask4
RELEASE loHttp
RELEASE loResp
RELEASE loHttp1
RELEASE loHttp2
RELEASE loHttp3
RELEASE loHttp4
RELEASE loSbRange
CANCEL
ENDIF
* All downloads were successful.
* Compose the file from the parts.
loFac = CreateObject('Chilkat.FileAccess')
lnSuccess = loFac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml")
IF (lnSuccess = 0) THEN
? loFac.LastErrorText
ELSE
? "Success."
ENDIF
RELEASE loTask1
RELEASE loTask2
RELEASE loTask3
RELEASE loTask4
* Let's download in the regular way, and then compare files..
lnSuccess = loHttp.Download(lcUrl,"qa_output/hamletRegular.xml")
* Compare files.
lnBSame = loFac.FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml")
? "bSame = " + STR(lnBSame)
RELEASE loHttp
RELEASE loResp
RELEASE loHttp1
RELEASE loHttp2
RELEASE loHttp3
RELEASE loHttp4
RELEASE loSbRange
RELEASE loFac