PureBasic
PureBasic
SFTP Upload Large File in Parts
See more SFTP Examples
Demonstrates how to split a large file into N parts and then upload each part separately. This technique can be used to potentially avoid limits a SFTP server might impose on upload file size.Chilkat PureBasic Downloads
IncludeFile "CkBinData.pb"
IncludeFile "CkSFtp.pb"
IncludeFile "CkFileAccess.pb"
Procedure ChilkatExample()
success.i = 0
; This example assumes the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
sftp.i = CkSFtp::ckCreate()
If sftp.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Set some timeouts, in milliseconds:
CkSFtp::setCkConnectTimeoutMs(sftp, 5000)
CkSFtp::setCkIdleTimeoutMs(sftp, 10000)
; Connect to the SSH server.
; The standard SSH port = 22
; The hostname may be a hostname or IP address.
hostname.s = "sftp.example.com"
port.i = 22
success = CkSFtp::ckConnect(sftp,hostname,port)
If success <> 1
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
ProcedureReturn
EndIf
; Authenticate with the SSH server. Chilkat SFTP supports
; both password-based authenication as well as public-key
; authentication. This example uses password authenication.
success = CkSFtp::ckAuthenticatePw(sftp,"myLogin","myPassword")
If success <> 1
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
ProcedureReturn
EndIf
; After authenticating, the SFTP subsystem must be initialized:
success = CkSFtp::ckInitializeSftp(sftp)
If success <> 1
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
ProcedureReturn
EndIf
; Open a remote file for writing on the SSH server.
; If the file already exists, it is overwritten.
; (Specify "createNew" instead of "createTruncate" to
; prevent overwriting existing files.)
handle.s = CkSFtp::ckOpenFile(sftp,"big.zip","writeOnly","createTruncate")
If CkSFtp::ckLastMethodSuccess(sftp) <> 1
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
ProcedureReturn
EndIf
; We're going to upload the local file "qa_data/zips/big.zip" (a relative local path from our current working directory)
; to the SFTP server.
localFilePath.s = "qa_data/zips/big.zip"
; Rather than uploading in one shot, we'll read the local file in chunks
; and upload a chunk at a time.
fac.i = CkFileAccess::ckCreate()
If fac.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkFileAccess::ckOpenForRead(fac,localFilePath)
If success = 0
CkSFtp::ckCloseHandle(sftp,handle)
Debug CkFileAccess::ckLastErrorText(fac)
CkSFtp::ckDispose(sftp)
CkFileAccess::ckDispose(fac)
ProcedureReturn
EndIf
; If we were to split the local file into 128K chunks, how many chunks (blocks) would
; we have, including the last partial block?
blockSize.i = 131072
numBlocks.i = CkFileAccess::ckGetNumBlocks(fac,blockSize)
Debug "Number of blocks = " + Str(numBlocks)
bd.i = CkBinData::ckCreate()
If bd.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
i.i = 0
While i < numBlocks
; Read the Nth block, which gets appended to the bd. (which means
; we must clear the contents of bd before the next iteration)
success = CkFileAccess::ckReadBlockBd(fac,i,blockSize,bd)
If success = 0
CkSFtp::ckCloseHandle(sftp,handle)
Debug CkFileAccess::ckLastErrorText(fac)
CkSFtp::ckDispose(sftp)
CkFileAccess::ckDispose(fac)
CkBinData::ckDispose(bd)
ProcedureReturn
EndIf
; Upload this block to the open remote file.
success = CkSFtp::ckWriteFileBd(sftp,handle,bd)
If success = 0
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
CkFileAccess::ckDispose(fac)
CkBinData::ckDispose(bd)
ProcedureReturn
EndIf
; Clear the contents for the next iteration.
CkBinData::ckClear(bd)
i = i + 1
Wend
; Close the local file.
CkFileAccess::ckFileClose(fac)
; -----------------------------------------------------------------------------
; This is important. You must close the handle on the server.
; Otherwise open handles will accumulate on the server until eventually a limit
; is reached and the server will fail on a call to OpenFile.
; -----------------------------------------------------------------------------
; Close the remote file handle on the server.
success = CkSFtp::ckCloseHandle(sftp,handle)
If success <> 1
Debug CkSFtp::ckLastErrorText(sftp)
CkSFtp::ckDispose(sftp)
CkFileAccess::ckDispose(fac)
CkBinData::ckDispose(bd)
ProcedureReturn
EndIf
Debug "Success."
CkSFtp::ckDispose(sftp)
CkFileAccess::ckDispose(fac)
CkBinData::ckDispose(bd)
ProcedureReturn
EndProcedure