Before submitting ZIP files to various third parties, I often have the need to ether remove superfluous files from my archives. Until today I’ve never had the need to add a file to such archives. Had that happened in the past, I would have probably just deleted the whole archive and crated a new one from scratch.
Today I felt adventurous and researched a way to add files to existing ZIP files and found a (not-so-obvious) solution to this puzzle, using the -r switch.
Let me show you how it works:
zip-rv YourArchive.zip NewFile.txt
According to the man page, the r switch actually replaces an existing file in the archive, so this command can be used to update files in the ZIP file too. I’ve added the v switch for convenience (it means “verbose” and can be omitted.
ZIP files can get quite large, depending on the amount of data we’re ZIPping up there. Having one huge file may not always be desirable, for example when making hard copies onto disk or tape media, or when upload limitations force the use of smaller files.
Thankfully, the clever little ZIP utility has a handy function that can split our archive into smaller chunks for later re-assembly. Here’s how it works:
This will create an archive of all files and subfolders in myfiles, creating a new file every 200MiB (about 10% more than 200MB). We can use K, G and T respectively (for KiB, GiB and TiB, all of which are 10% more than kilobyte, gigabyte and terabyte).
To clarify, the s switch will specify the size of each file, while the -r switch tells ZIP to do this operation recursively.
As a result, we’ll see a list of files like this:
To extract any or all of our files again, we can use the UNZIP utility. All we need to do now is to treat archive.zip as our main file and let UNZIP handle the rest. It will understand that all z** files are part of the multivolume archive. For example:
will list all files contained in our archive, not matter which files they’re physically contained in.
Should any of the volume files be missing or damaged, none of the archive can be read as far as I know. Make sure you leave them all in place and don’t try to open them by itself.
When ZIP up directories, particularly on macOS, some files may find their way into our ZIP archives that were never meant to be there. I’m thinking of those pesky .DS_Store and __MACOSX files, maybe even .htaccess files. For *nix based systems, * really means “everything”.
The ZIP command line tool let us remove such unwanted files from an existing archive. Here’s how:
zip-dyour-archive.zip file1 file2
The -d switch tells ZIP to hunt for and delete the unwanted files. Files whose names contain spaces can be defined in “regular quotes”, and the * asterisk can be used as usual.
For example, to remove all DS_Store files and __MACOSX files, we can use this:
To verify that such idiosyncrasies have indeed been removed from a ZIP archive before we release it into the wide, we can check with the UNZIP utility:
This will simply list the contents of your-archive.zip without actually extracting it.
Sometimes it’s easy to delete a ZIP file and create a new one – say you’ve forgotten to include a file. Just drag it into the folder to be ZIPped up and start again.
However, the clever little ZIP command line tool has a built-in ability to simply add a file to an existing archive without us having to do any manual grunt work. That can come in handy when we no longer have access to existing unZIPped content.
We can even add entire directories this way too, like so:
This will recursively add all files (indulging hidden and annoying ones) to our file.
Note that ZIP accomplishes this by temporarily extracting all files before creating a new archive for is (while deleting our original file). So in essence, the tools is doing what we’d do manually, just more conveniently and in the background without bothering us.
I’ve just realised how (relatively) easy it is to make PHP create a ZIP Archive from a directory and its sub directories.
Previously I had relied on the Linux Shell Command zip or tar to do this which is a convenient one liner. I had assumed that in PHP we had to go through each directory and add the files manually – until I’ve discovered the RecursiveIterator class variants.
In this example I’m defining a root path and a file name for my archive (change at will), then iterate through each file in each directory (and if thats’ a directory too, we’ll go one level deeper). The result of which is an array of files. We’ll get their full paths and add them to the ZIP archive.
echo'<p>There was a problem writing the ZIP archive.</p>';
echo'<p>Successfully created the ZIP Archive!</p>';
The above will produce a ZIP file which will contain references to the absolute full paths of each file. That’s great if you’d like to unzip those files later in exactly the same location – but it’s not so cool if you’re just interested in the content and the idea of 11 sub folders strikes you as “less funny”.
Help is at hand, thanks to the way we can add files to the archive – namely by creating a new local filename. Here’s an example of how this works on Linux systems:
// let's iterate and create a new local file name
No more references to absolute full paths in your ZIP file.