Zip files are one of the most common compression formats around, and are a great way of storing files. Using the userlib functionality of BlitzPlus and Blitz3D, it's now possible to access and manipulate zip files from within your Blitz applications. This can be useful for packing your media, as well as compressing network data.
This article will show you the following:
- What files you need to use zip files in Blitz, and how to install them.
- How to open an archive file and find out what files it contains.
- How to extract a file from an archive.
- How to create a new zip file and add files to it.
- How to compress and uncompress Blitz banks.
What will you need?
- Blitz.ZipApi – A free library that you can include in your Blitz project. It comes with everything you need to use zip functionality within Blitz.
Installing the files
Once you've downloaded the library, you'll need to copy "zlibwapi.dll" and "zlibwapi.decls" to the appropriate "userlibs" folder so that you can use the userlib functions in your application. This will be something similar to "c:\program files\blitzplus\userlibs\". The userlib file is fully documented and has XML comments for use with Protean IDE.
You're now able to use simple zip functions, but if you'd like to get easier access to some of the more common functions, you should include the following into your project:
- Blitz_File_ZipApi.bb – Helper functions for using zip files in Blitz.
- Blitz_File_FileName.bb – A few functions for manipulating file names. Use them to get a directory name, file name and extensions from a string.
- Blitz_Basic_Bank.bb – PeekString and PokeString functions.
All of these files are included in the Blitz.ZipApi distribution, along with full documentation in HTML format.
How it works
The zip library works in a similar fashion to the standard Blitz file
functions. Before a file can be read from it should be opened with
ZipApi_Open
, and once finished with it should be closed with
ZipApi_Close
. Files to be written to should be opened with ZipApi_CreateZip
and closed with ZipApi_CloseZip
.
Fully documented examples are included with the library, and are also available online.
Reading the contents of a zip file
Example source code can be found here.
The zip library includes several functions for iterating through the files in an archive that has been opened with ZipApi_Open. To start with, we need to open an archive file and move the internal "pointer" to the first file in the zip:
; Open the zip file Local zipIn = ZipApi_Open("myZip.zip") ; Move to the first file ZipApi_GotoFirstFile(zipIn)
To move to the next file in the archive, call ZipApi_GotoNextFile
.
This will return the constant value ZIPAPI_UNZ_END_OF_LIST_OF_FILE
if
the end of the archive has been reached.
; Get the current file's information Local fileInfo.ZIPAPI_UnzFileInfo = ZipApi_GetCurrentFileInfo(zipIn)
Calling ZipApi_GetCurrentFileInfo
gets information about the file currently
pointer at. This information is returned in as a type for ease of use. The
following fields are the most useful:
- FileName$ – The name of the file.
- ExtraField$ – Extra field data that is sometimes added in an archive.
- Comment$ – An optional comment about this file.
- Crc32% – The CRC-32 value of the file. This is used to check the file has been unpacked properly.
- CompressedSize% – The compressed size of the file (in bytes).
- UnCompressedSize% – The Un-compressed size (in bytes).
Once you're finished with the object, call ZIPAPI_UnzFileInfo_Dispose
with the
ZIPAPI_UnzFileInfo object as a parameter. This is similar to using Blitz's
"delete" function, except it takes care of freeing up bank handles and other
internals.
Extracting a file from an archive
Example source code for extracting files can be found here.
Extracting a file from an open archive is quite simple. Simply call
ZipApi_ExtractFile
with the handle of the opened file and the name of the file
to extract, and the rest is done for you. The function will return the full path
to the file that was extracted, so can be used within LoadImage and similar
functions.
Creating a new zip file
Example source for creating zip files can be found here.
Creating a new zip file is another standard operation. Like reading from a zip file, a file handle must be opened first. However, writing an archive requires a different function to open it.
; Open our new archive Local zipOut = ZipApi_CreateZip("my-test.zip")
Once the archive has been opened, adding files is a case of calling
ZipApi_AddFile
with an open zip handle and the name of the file you wish to
compress.
; Add a file Local zipOut = ZipApi_AddFile(fileOut, "my-file.txt")
One useful feature is the ability to add a bank directly to a zip file. The
ZipApi_AddBankAsFile
function allows you to add a bank directly. This can be
very useful if you're creating dynamic data you wish to compress, such as
something downloaded directly from the internet or created in memory.
ZipApi_AddBankAsFile(zipOut, bankToAdd, "test-file.txt")
Once all files have been added, call ZipApi_CloseZip
to close the
archive. That's all there is to it!
Compressing a bank
Example source for compressing and uncompressing banks can be found here.
Compressing and uncompressing banks is very straightforward. Only two functions
are required: ZipApi_Compress
and ZipApi_UnCompress
. Both of these functions
take the handle of a blitz bank, and both return the handle to a new bank
containing the packed/unpacked data.
You may wish to pack a bank for a number of reasons. It can be useful for sending data over a network, such as maps or character data.
Further reading
The full documentation for Blitz.ZipApi is available here, and contains a several examples and full explanations for all of the common functions in the library.