PureBasic
PureBasic
Streaming Compression
See more Compression Examples
Compress and decompress using a stream.Chilkat PureBasic Downloads
IncludeFile "CkTask.pb"
IncludeFile "CkCompression.pb"
IncludeFile "CkStream.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.
fac.i = CkFileAccess::ckCreate()
If fac.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
compress.i = CkCompression::ckCreate()
If compress.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCompression::setCkAlgorithm(compress, "deflate")
streamC.i = CkStream::ckCreate()
If streamC.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; This example sets the source and sink of the stream to files.
; A stream can have use other streams as a source or sink,
; or the application can itself be the source/sink by directly
; reading or writing a stream. (See below for an example of this..)
CkStream::setCkSourceFile(streamC, "qa_data/hamlet.xml")
CkStream::setCkSinkFile(streamC, "qa_output/hamlet_compressed.dat")
; Compress from source to sink.
success = CkCompression::ckCompressStream(compress,streamC)
If success <> 1
Debug CkCompression::ckLastErrorText(compress)
CkFileAccess::ckDispose(fac)
CkCompression::ckDispose(compress)
CkStream::ckDispose(streamC)
ProcedureReturn
EndIf
Debug "File-to-file deflate compression successful."
; Note: The FileSize method returns a signed 32-bit integer. If the file is potentially larger than 2GB, call FileSizeStr instead to return
; the size of the file as a string, then convert to an integer value.
Debug "Original size = " + Str(CkFileAccess::ckFileSize(fac,CkStream::ckSourceFile(streamC)))
Debug "Compressed size = " + Str(CkFileAccess::ckFileSize(fac,CkStream::ckSinkFile(streamC)))
; Now do file-to-file decompression
streamD.i = CkStream::ckCreate()
If streamD.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStream::setCkSourceFile(streamD, "qa_output/hamlet_compressed.dat")
CkStream::setCkSinkFile(streamD, "qa_output/hamlet_restored.xml")
; Decompress from source to sink.
success = CkCompression::ckDecompressStream(compress,streamD)
If success <> 1
Debug CkCompression::ckLastErrorText(compress)
CkFileAccess::ckDispose(fac)
CkCompression::ckDispose(compress)
CkStream::ckDispose(streamC)
CkStream::ckDispose(streamD)
ProcedureReturn
EndIf
Debug "File-to-file deflate decompression successful."
; Let's double-check to see that the files are equal in size and content:
bFilesEqual.i = CkFileAccess::ckFileContentsEqual(fac,CkStream::ckSourceFile(streamC),CkStream::ckSinkFile(streamD))
If bFilesEqual <> 1
Debug "The output file is not equal to the input file!"
Else
Debug "The file was successfully compressed and decompressed."
EndIf
; ---------------------------------------------------------------------
; Now let's decompress again, but this time w/ the application reading
; the decompressed data directly from a stream.
streamA.i = CkStream::ckCreate()
If streamA.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStream::setCkSourceFile(streamA, "qa_output/hamlet_compressed.dat")
; Start decompressing in a background thread.
task.i = CkCompression::ckDecompressStreamAsync(compress,streamA)
success = CkTask::ckRun(task)
; Read decompressed data from streamA:
decompressedText.s
While (CkStream::ckEndOfStream(streamA) <> 1)
If CkStream::ckDataAvailable(streamA) = 1
decompressedText = CkStream::ckReadString(streamA)
Debug decompressedText
EndIf
Wend
; Let's make sure the background task finished and that the decompress was successful.
; It should already be the case that the task is finished.
While (CkTask::ckFinished(task) <> 1)
CkTask::ckSleepMs(task,20)
Wend
; The decompressor may have finished, but it is possible that data
; remains to be flushed.
If CkStream::ckDataAvailable(streamA) = 1
decompressedText = CkStream::ckReadString(streamA)
Debug decompressedText
EndIf
; Did streamA succeed in reading the entire file?
If CkTask::ckTaskSuccess(task) <> 1
Debug "async decompress failed:"
Debug CkTask::ckResultErrorText(task)
success = 0
EndIf
Debug "The async decompress was successful."
CkFileAccess::ckDispose(fac)
CkCompression::ckDispose(compress)
CkStream::ckDispose(streamC)
CkStream::ckDispose(streamD)
CkStream::ckDispose(streamA)
ProcedureReturn
EndProcedure