Introducing Tcl 8.7 Part 11: The ZIP virtual file system


This is the eleventh in a series of posts about new features in the upcoming version 8.7 of Tcl. It is the first of a pair of posts describing core support for treating ZIP archives as virtual file systems within Tcl. This post focuses on base operations dealing with existing ZIP archives. The next describes the creation of ZIP archives and their use for building zipkits and single file executables.

To take Tcl 8.7 for a spin, you can download the source distribution. Binary distributions for Windows are available from magicsplat and BAWT.

With Tcl 8.6, access to files in ZIP archives was already possible. Tcl itself offered the ability to compress and decompress data with the zlib command. The zipfile module in tcllib then made use of these to permit access to files within an archive.

Tcl 8.7 goes beyond these capabilities by treating ZIP archives as mountable virtual file systems (VFS). This makes access to the files within the archive much simpler through the standard Tcl channel commands open, gets etc.

Mounting ZIP archives

The first step to accessing ZIP archives is to mount them as a Tcl VFS. This is done with the zipfs mount command.

% zipfs mount mnt

This results in the archive being mounted as a VFS under the path zipfs:/mnt.

The root of all ZIP file systems is given by the zipfs root command.

% zipfs root

This root is platform-specific, zipfs:/ on Windows and //zipfs:/ on Unix(y) systems.

Naturally, you can mount multiple archives or even the same archive multiple times. The mount points of course have to be different but one can be nested inside another. For example,

% zipfs mount mnt2
% zipfs mount mnt/nested

Invoking zipfs mount without any arguments will return the currently mounted ZIP archives as a flat list of mount points and the archive file path.

% zipfs mount
zipfs:/mnt zipfs:/mnt/nested zipfs:/mnt2

ZIP archives may be protected with a password. In that case the password must be supplied as the last argument to the command.

When no longer needed the each VFS should be unmounted with zipfs unmount.

% zipfs unmount mnt2
% zipfs unmount mnt/nested
% zipfs mount

Introspecting archives

Once mounted, the archives can be introspected.

The zipfs list command returns a list of the files in the ZIP file system. Optionally, regular expression or glob wildcard patterns may be specified to filter the returned paths.

% zipfs list
zipfs:/mnt/demo zipfs:/mnt zipfs:/mnt/demo/subdir/file.txt zipfs:/mnt/demo/subdir zipfs:/mnt/demo/demo.txt
% zipfs list *.txt
zipfs:/mnt/demo/subdir/file.txt zipfs:/mnt/demo/demo.txt
% zipfs list -glob *.txt
zipfs:/mnt/demo/subdir/file.txt zipfs:/mnt/demo/demo.txt
% zipfs list -regexp {\.txt$}
zipfs:/mnt/demo/subdir/file.txt zipfs:/mnt/demo/demo.txt

Notice there is no mount point specified above. The command lists all files and directories under the ZIP VFS root. To restrict to a specific archive, specify it as a pattern.

A similar command returns a list of all file paths under a specific directory.

% zipfs find zipfs:/mnt/demo/subdir

TIP: The zipfs find command will work with any file system, not just ZIP VFS'es.

Since the ZIP archive is mounted as a Tcl VFS, standard Tcl commands for retrieving generic file information can be used. For example,

% file size zipfs:/mnt/demo/demo.txt
% clock format [file atime zipfs:/mnt/demo/demo.txt]
Sun Aug 23 12:33:24 IST 2020

The zipfs info command returns additional information that is specific to the ZIP archive format.

% zipfs info zipfs:/mnt/demo/demo.txt 12 14 50

The returned list contains the name of the ZIP archive (as originally passed), the original file size, the compressed file size and the offset of the file's compressed data within the ZIP archive. (As an aside, note in our example that the "compressed" size is greater than the actual size as often happens for small files.)

File I/O

Data transfer from compressed files in the archive is achieved through the standard Tcl channel I/O commands.

% set chan [open zipfs:/mnt/demo/demo.txt]
% gets $chan
Demo file 
% close $chan

You can also open the file for writing. However, the ZIP VFS does not support the append mode.

Coming up

Having described the basics of access to ZIP archives, in the next post I will illustrate the use of the new features for creating ZIP archives, zipkits and single-file executables.


  1. TIP 430: Add basic ZIP archive support to Tcl

  2. zipfs man page