How to compress files on the fly

Trevor DeVore lists at
Wed Nov 22 15:15:26 EST 2006

On Nov 22, 2006, at 9:21 AM, Stephen Barncard wrote:

> Hi gang,
> I'm messing around with the compress() function.
> My goal is to compress an .app package then upload it to an ftp  
> server.
> Right now the below code works on small files but seems to choke on  
> a 300mb file.
> I have a few questions:
> 1. in order to compress a MacOSX 'package',do I have to devise a  
> 'walker' to identify and compress each file separately inside? yikes.

Compress works with binary data so you can't package a folder  
directly.  For small files like OS X externals I've used the attached  
routine to store compressed versions of each file along with it's  
folder in a Rev object.  I only use it on known data so if you plan  
on using it with user supplied information you might need to add some  
more safety checks.

> 2. Will the compress function work like this between two files:
>  put compress(URL  tPRE) into URL  tPOST   ?? I can get it to work  
> for small files now...

I haven't tried this before so no comment.

> 3. Also after reviewing compress() I think I like the new zip  
> routines better - the progress callbacks are well worth it fo big  
> files.
>  But there's no revZipFolder command, which is really what I'm  
> looking for. That would really complete the zip library...

You could probably modify the attached handler to work with revZip as  
it walks through the provided directory using a recursive call.  One  
thing to keep in mind when adding directories is:

1) You can't add a folder to a zip archive with revZip.  You have to  
add a file in a folder.
2) When calling revZipAddItemWithFile and working with folders the  
2nd parameter should be the relative path to your file.  So if you  
were compressing the folder "/some folder/folder being compressed"  
and there was a file "/some folder/folder being compressed/some other  
folder/some file.txt" then the itemName (2nd) parameter would be  
"some other folder/some file.txt".

Trevor DeVore
Blue Mango Learning Systems -
trevor at

* Saves the contents of a folder to a custom property set of an object.
* @param  pObj         long id of object where custom property set  
will be stored.
* @param  pRoot        Path to root folder.
* @param  pFolder      folder within root being acted on.  Used  
recursively, don't pass.
* @return Empty OR error msg.
ON sys_saveFolderToObj pObj, pRoot, pFolder
     local tDefault,tFiles,tFolders,tFile,tLine
     local e,tError
     IF pFolder is empty THEN put pRoot into pFolder

         IF there is a folder pFolder THEN
             put defaultfolder into tDefault
             set defaultfolder to pFolder

             put files() into tFiles
             REPEAT for each line tLine in tFiles
                 put pFolder & slash & tLine into tFile
                 get offset(pRoot, tFile)
                 IF it = 1 THEN delete char 1 to length(pRoot) of tFile
                 ELSE throw "Folder is not within root folder:" &&  
pFolder & slash & tLine

                 set the uFolderFiles[tFile] of pObj to compress(URL  
("binfile:"& pFolder&slash&tLine))
             END REPEAT

             put folders() into tFolders
             REPEAT for each line tLine in tFolders
                 IF tLine = ".." THEN next REPEAT

                 put pFolder & slash & tLine into tFile
                 get offset(pRoot, tFile)
                 IF it = 1 THEN delete char 1 to length(pRoot) of tFile
                 ELSE throw "Folder is not within root folder:" &&  
pFolder & slash & tLine

                 set the uFolderFolders[tFile] of pObj to 1  -->  
                 sys_saveFolderToObj pObj, pRoot, pFolder & slash &  
             END REPEAT
         END IF
     CATCH e
         put e into tError
         set defaultfolder to tDefault
     END TRY

     return tError
END sys_saveFolderToObj

-- Reverse of sys_saveFolderToObj
ON sys_saveObjToFolder pObj, pFolder
     put the filetype into theFileType
     set the filetype to empty

         REPEAT for each line theKey in customkeys["uFolderFolders"]  
of pObj
             sys_createAllFoldersInPath pFolder & theKey, pFolder
             IF the result is not empty THEN throw the result
         END REPEAT

         --> EXPORT FILES
         REPEAT for each line theKey in customkeys["uFolderFiles"] of  
             put decompress(the uFolderFiles[theKey] of pObj) into  
URL ("binfile:"& pFolder & theKey)
             IF the result is not empty THEN throw the result
         END REPEAT

     CATCH e
         put e into theError
     END TRY

     set the filetype to theFileType

     return theError
END sys_saveObjToFolder

* Creates all folders in a provided path.
* @param pPath     Full path to be created.
* @param pRootPath Root folder to start creating from.  This is a  
folder that already exists.
* @return Error msg
ON sys_createAllFoldersInPath pPath, pRootPath
     local tChoppedPath  = ""

     set itemdel to slash

     --> VALIDATE pRootPath
     IF pRootPath is empty THEN
         put item 1 to 2 of pPath into pRootPath
         IF char 1 to (number of chars of pRootPath) of pPath is not  
pRootPath THEN
             return "path is not a child of root path"
         END IF

         IF last char of pRootPath = slash THEN delete last char of  
     END IF

     IF there is not a folder pRootPath THEN return "root path does  
not exist"
     IF number of items of pPath <= number of items of pRootPath THEN  
return empty

     put pRootPath & slash & item (number of items of pRootPath + 1)  
of pPath into tChoppedPath

     IF there is not a folder tChoppedPath THEN
         create folder tChoppedPath
         IF the result is not empty THEN return the result
     END IF

     sys_createAllFoldersInpath pPath, tChoppedPath

     return empty
END sys_createAllFoldersInPath

More information about the Use-livecode mailing list