Learning ColdFusion 8: CFZip Part V - Deleting Zip File Archives

Posted July 26, 2007 at 7:20 AM

Tags: ColdFusion

In the previous parts of this series, we looked at how to make, read, and extract zip archive files using ColdFusion 8's new CFZip and CFZipParam tags. Now, let's finish this up taking a quick look at how we can delete entries within a zip archive. I'm not talking about deleting the actual Zip file - that would best be done using CFFile - I'm talking about deleting items within the archive file. Since this is, by far, the least interesting of all the actions, I am gonna try to keep this brief.

As always, before we can start exploring the deleting of an archive in ColdFusion 8, we have to create a zip archive to work with. We are going to zip the following directory structure:

./data/documents/manual.txt
./data/documents/readme.txt
./data/images/funny.jpg
./data/images/mud_monster.jpg
./data/images/red_face.jpg
./data/images/smile.jpg

To create the zip, we are going to use the simple ColdFusion 8 CFZip tag:

 Launch code in new window » Download code as text file »

  • <!---
  • Create a zip archive of the data directory.
  • By default, ColdFusion 8 will recurse the
  • source directory, store the storage paths,
  • and do to our use of Overwrite attribute, we
  • will make sure we create a new zip archive.
  • --->
  • <cfzip
  • action="zip"
  • source="#ExpandPath( './data/' )#"
  • file="#ExpandPath( './data.zip' )#"
  • overwrite="true"
  • />

This will put all contents of the data directory into the root of our zip archive (the documents and images directory). Now that have a zip archive, the easiest thing we can do is delete everything inside of it using the delete action:

 Launch code in new window » Download code as text file »

  • <!--- Delete all contents of the Zip archive. --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#"
  • />

Ok, maybe not. This action actually throws the following ColdFusion error:

Cannot delete all the entries from a zip file. There should be at least one entry remaining in the zip file.

When deleting zip archive entries in ColdFusion 8, you have to be careful to leave at least one entry. This also helps us to draw the conclusion that ColdFusion 8 does not allow you have empty directory entries in the archive (despite the fact that listing archive entries can have a type of Directory). In order to avoid this, we can modify the delete action to make sure we only delete certain files. The least destructive thing we can do is to delete a single file using the EntryPath attribute:

 Launch code in new window » Download code as text file »

  • <!--- Delete the readme.txt file. --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#"
  • entrypath="documents/readme.txt"
  • />

Here, we are deleting the readme.txt file located within the documents folder. As with zip archive extracting, the EntryPath attribute cannot start with the "./" or "/" path constructs. Again, ColdFusion 8 will not thrown any error, it simply won't see the file you are referring to.

To make the action slightly more destructive, we can delete an entire folder by using an EntryPath that references a directory entry:

 Launch code in new window » Download code as text file »

  • <!--- Delete the documents directory. --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#"
  • entrypath="documents"
  • />

Here, we are deleting the entire documents folder. And again, this EntryPath must not start or end with any "/" path constructs or ColdFusion will simply not find the entry you are referring to.

When we start to delete multiple files at once, as we just did above, we can use the Filter attribute to selectively include files in our zip modification. As we have discussed many times before, the Filter file mask can use the wild card * as well as take a comma delimited list of file masks. In this next example, we will delete entries in the documents folder, but only those that are manuals:

 Launch code in new window » Download code as text file »

  • <!---
  • Delete any manual files that are located
  • within the documents directory.
  • --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#"
  • entrypath="documents"
  • filter="manual*"
  • />

This will delete the manual.txt but it will leave the readme.txt file in place.

By default, all delete actions on the zip archive are recursive. That means that if a directory has subdirectories, ColdFusion 8 will delete all files and folders in the target entrypath directory. Therefore, if we simply remove the EntryPath from the example above:

 Launch code in new window » Download code as text file »

  • <!---
  • Delete any manual files that are located
  • anywhere within the zip archive.
  • --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#"
  • filter="manual*"
  • />

... we will end up with the same exact result (deleting the manual.txt file in the documents folder). This is because removing the EntryPath will point the delete action at the root of the archive. Then, since ColdFusion 8 zip actions are recursive by default, it will eventually recurse through the subfolders (documents and images) and find the manual.txt file to delete.

To turn off recursive delete, simply set the Recurse attribute to False. This will ensure that only the FILES within the target directory will be deleted and that the subdirectories will not be touched.

As with all CFZip actions, deleting can also be done by using the CFZip tag in conjunction with nested CFZipParam tags. EntryPath, Filter, and Recurse can all be moved into one or more CFZipParam tags. Remember that each CFZipParam tag represents an action; therefore, the Filter attribute of one CFZipParam tag applies only to itself and to no other sibling tags. The same is true for Recurse and EntryPath. To mimic the manual.txt deletion above, we can move the appropriate attributes down into a child tag:

 Launch code in new window » Download code as text file »

  • <!---
  • Delete any manual files that are located
  • anywhere within the zip archive.
  • --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#">
  •  
  • <!--- Delete manual files. --->
  • <cfzipparam filter="manual*" />
  •  
  • </cfzip>

And of course, we can have more than one CFZipParam tag. In this next example, we will delete the manual files and the entire images directory:

 Launch code in new window » Download code as text file »

  • <!---
  • Delete any manual files that are located
  • anywhere within the zip archive. Also delete
  • the entire images directory.
  • --->
  • <cfzip
  • action="delete"
  • file="#ExpandPath( './data.zip' )#">
  •  
  • <!--- Delete manual files. --->
  • <cfzipparam filter="manual*" />
  •  
  • <!--- Delete the images directory. --->
  • <cfzipparam entrypath="images" />
  •  
  • </cfzip>

This will leave us with a zip archive that has just one entry:

./documents/readme.txt

So there you have it. Sorry if this part of the series was a bit brief, but I think we have beaten ColdFusion 8's new CFZip tag into the ground. On top of that, I think deleting zip entries is going to be used the least of all the actions.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page


You Might Also Be Interested In:



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

There are no comments posted for this web log entry.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 20, 2009 at 5:38 PM
Learning ColdFusion 8: CFImage Part I - Reading And Writing Images
Hi Ben, Great article. I've been looking around to see if ColdFusion image engine can programatically create the following "wrap around" effect: http://www.creativepro.com/article/photoshop-s-she ... read »
Nov 20, 2009 at 5:35 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Dave: I talked to Gert he suggested: <cfhttp method="get" url="http://{some cf website}" result="stuff" addtoken="yes" /> Note the addition of cfhttp attribute addtoken. That should persist y ... read »
Nov 20, 2009 at 5:23 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Todd, Ahh, gotcha, yeah that makes sense. ... read »
Nov 20, 2009 at 5:17 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
Ben, sorry if I didn't make this clear. You can make it work like that if you want, just put <cfset session.foo = 1> (and <cfset application.foo = 1>) in your OnRequestStart() and it reve ... read »
Nov 20, 2009 at 5:07 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Todd, I have seen tidbits about the way Railo handles session. I can understand that it lazy-loads sessions, but I also think that I might make some things more complicated. For example, often tim ... read »
Nov 20, 2009 at 4:53 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
Ben, you can ramp up the security by turning on J2EE session which gives you a third set of numbers other than CFID/CFTOKEN. There's a reason why ACF put this in place (other than just session replic ... read »
Nov 20, 2009 at 4:52 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
Case in point, Ben, you may not be aware of this, but in Railo - OnApplicationStart() & OnSessionStart() act differently than in ACF. ACF does: OnApplicationStart (1st hit) OnSessionStart (1st and e ... read »
Nov 20, 2009 at 4:46 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Todd, That's understandable. I am not sure if this really leaves any more security holes than the fact that using old cookie-based CFID / CFTOKEN values will create a new session using the old CFI ... read »