Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP Compression by Craig Boyd - Thanks again!

Status
Not open for further replies.
I am hoping Craig will respond to this - so I can give him a star.

I've been using his VFP Compression for years and it's brill. Today a customer wanted a tiny
tweak to his system and all I had to do was modify a call to FileZip to be FileZipRelative and
it just worked and the client is happy and so am I.

So, here's to you Craig, thank you for a good bit of s/w with excellent documentation.



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
what he said !



 
Indeed I use it and like it for it's callback. I wrote a little wrapper for it, which shows zip/unzip progress in the status bar. It's limited to zip of a complete folder and unzip of a complete zip archive, but that's sufficient in most cases anyway. See:
The only thing I still miss is being able to compress at different levels. Eg for very slow vpn connections before sending a zip file, compressing it with highest compression level still can save most time, even though the compression itself takes a bit longer.

There is only one function enabling you to set a compression level: The ZipString function. But it's compression level parameter doesn't have an effect on the string zipping:
Code:
For lnLevel = 1 to 9
? Len(ZipString(Replicate("This is a test Text.",1000),lnLevel))
EndFor
It'll always be the same compressed length. I'm using the latest download of the FLL Craig offered in December 2008. Besides, even if it would work, it wouldn't work for ZipFile(), would it.

I have an alternative for single files, using zlib. You can download the binary zlib1.dll from and then use it with these declarations:
Code:
Declare Integer gzopen In "zlib1.dll";
   STRING @ Path, String @ Mode
Declare Integer gzclose In "zlib1.dll";
   INTEGER FileHandle
Declare Integer gzread In "zlib1.dll";
   INTEGER FileHandle, String @ Buffer, Integer BufferLength
Declare Integer gzwrite In "zlib1.dll";
   INTEGER FileHandle, String @ Buffer, Integer BufferLength

There's more in it, but that's sufficient for file zipping. gzopen works like fopen or fcreate. It allows you to open existing gz files or create a new one, which merely is specified by the mode parameter. Use "rb" for read and "wbN" for write, with N from 1 to 9 specifying the compression level, wb for standard compression (5 or 6) and wbT for no compression (eg for uncompressing). In short use these two functions to compress (deflate) or uncompress (inflate) single files.

Code:
Function DeflateFile(tcFilename, tlDeleteOriginalFile)
   If Not (Left(tcFilename,2)=="\\" Or Substr(tcFilename,2,1)=":")
      tcFilename = Fullpath(tcFilename)
   Endif
   If Adir(laDummy,tcFilename)=0
      Error 1 && file does not exist
   Endif
   If Adir(laDummy,tcFilename+".gz")=1
      Error 7 && file already exists
   Endif

   Local lnSourceFileHandle, lnGZFileHandle, lcBlock, llError
   lcBlock = Space(0x8000)
   lnGZFileHandle = gzopen(tcFilename+".gz","wb9")
   lnSourceFileHandle = gzopen(tcFilename,"rb")
   If lnGZFileHandle >0 And lnSourceFileHandle >0
      Try
         Do While .T.
            lnBytesRead = gzread(lnSourceFileHandle, @lcBlock, Len(lcBlock))
            If lnBytesRead>0
               gzwrite(lnGZFileHandle,@lcBlock,lnBytesRead)
            Else
               Exit
            Endif
         Enddo
      Catch
         llError = .T.
      Finally
         gzclose(lnGZFileHandle)
         gzclose(lnSourceFileHandle)
         If NOT llError OR tlDeleteOriginalFile
            Erase (tcFilename)
         Endif
      Endtry
   Endif
Endfunc

Function InflateFile(tcFilename, tlDeleteOriginalFile)
   If Not (Left(tcFilename,2)=="\\" Or Substr(tcFilename,2,1)=":")
      tcFilename = Fullpath(tcFilename)
   Endif
   If Adir(laDummy,tcFilename)=0 Or Not Lower(Justext(tcFilename))=="gz"
      Error 1 && file does not exist (or isn't GZ file)
   Endif

   Local lnDestFileHandle, lnGZFileHandle, lcBlock, llError
   lcBlock = Space(0x8000)
   lnGZFileHandle = gzopen(tcFilename,"rb")
   lnDestFileHandle = gzopen(Forceext(tcFilename,""),"wbT") && write without compression
   If lnGZFileHandle>0 And lnDestFileHandle>0
      Try
         Do While .T.
            lnBytesRead = gzread(lnGZFileHandle, @lcBlock, Len(lcBlock))
            If lnBytesRead>0
               gzwrite(lnDestFileHandle,@lcBlock,lnBytesRead)
            Else
               Exit
            Endif
         Enddo
      Catch
         llError = .T.
      Finally
         gzclose(lnDestFileHandle)
         gzclose(lnGZFileHandle)
         If NOT llError OR tlDeleteOriginalFile
            Erase (tcFilename)
         Endif
      Endtry
   Endif
Endfunc

The incapability of vfpcompression to zip with different compression levels is less important to me, as having a single zip archive file is even more important than how good the compression is.

Bye, Olaf.
 
Sorry, it should be NOT llError AND tlDeleteOriginalFile, as the intention is to only delete the file passed in, if the deflate/inflate has worked AND the caller specified it should be deleted.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top