NAME

IO::File::CompressOnClose - compress a file when done writing to it

SYNOPSIS

use IO::File::CompressOnClose;
my $io = IO::File::CompressOnClose->new('>foo');
print $io "foo bar baz\n";
$io->close;  # file will be compressed to foo.gz on unix or
             # foo.zip on Windows

To change compression schema to a class (which is expected to have a ->compress() class method):

$io->compressor('Foo::Bar');

To change compression scheme to an arbitrary coderef:

$io->compressor(\&coderef);

DESCRIPTION

To conserve disk space, it can be helpful to compress files that your program creates as soon as possible. The IO::Zlib module is a great way to do this, but it suffers from one (unavoidable) drawback: the files are only accessible as compressed files.

What IO::File::CompressOnClose provides is an IO::File compatible way to have the files created by your program written out as plain text files but compressed when they are closed. This allows you to tail a file using a vanilla 'tail -f' without having to worry about manually compressing the file when direct access to it is no longer necessary.

You open a file using IO::File::CompressOnClose in much the same was as you would open a file using IO::File (with one caveat; see below). If you construct an object of class IO::File::CompressOnClose then the compression scheme will be chosen based upon your platform (Zip for DOS/Windows and Gzip for any other platform).

If you prefer to choose the specific compression scheme ahead of time you can instantiate an object of a subclass of IO::File::CompressOnClose. The Zip and Gzip subclasses are part of this distribution; other compression schemes may be supported in the future.

When compression takes places, the original file is deleted; you can disable this behaviour by setting the delete_after_compress attribute.

FILE NAMES

After the file is opened using IO::File, a test is made to see if the file exists. If this test fails, an exception is thrown. This is a crude but hopefully effective way to prevent using esoteric filenames (+> or >&2) or piped opens (|/bin/date).

FILE MODES

At present, IO::File::CompressOnClose is not terribly clever about file modes. It can only handle file modes of the form ">file" or "file", "w". Attempts to use numeric modes or IO layers will throw an exception.

Supporting these other modes may be considered for future versions of this module depending on user interest.

ACCESSORS

An IO::File::CompressOnClose object has several get/set accessor methods. When used to set an attribute, the accessors return the previous value of the attribute.

filename()

The absolute filename that will be compressed upon close. It would be unwise to change this unless you know what you are doing.

compress_to()

The absolute filename that the compressed file will take. If this is set prior to the file being closed then the specific name will be used. Otherwise the name will be generated by the compression class or subroutine.

If all you wish to do is override the default compression suffix (say to use .gzip instead of .gz) then you should be careful to add the suffix to the absolute source file path using the ->filename() accessor:

$io->compress_to( $io->filename . '.gzip' );

compressor()

The class to be used for compression, or a coderef that will perform the same task. This attribute will be set when the file is first opened, and may be modified thereafter.

For details on the calling syntax of the class or coderef, see "SUBCLASSING" and "USING AN ANONYMOUS SUBROUTINE TO COMPRESS" below.

compress_on_close()

This accessor will return 1 or 0 to indicate whether the file will be compressed on close. For files opened for write or append, this will be 1. For files opened for read, this will be 0.

If a file is opened for write but subsequent events dictate that the file not be compressed on close, this method may be used to change the attribute prior to closing the file.

delete_after_compress()

This accessor will return 1 or 0 to indicate whether the original file will be deleted after being compressed.

compressed()

This accessor will return 1 or 0 to indicate whether the file has been compressed or not.

SUBCLASSING

To support a new compression scheme, follow the layout of one of the existing subclasses (Zip or Gzip).

Your class must meet these requirements:

  • it must be loadable (duh)

  • it must be a subclass of IO::File::CompressOnClose.

  • it must have a compress method.

When the class is successfully loaded, the IO::File::CompressOnClose object will be re-blessed into the new class. The compress method will then be invoked on the object with two parameters: the source file name and the destination file name. If the destination file name is undefined, the method should choose a suitable default.

USING AN ANONYMOUS SUBROUTINE TO COMPRESS

As an alternative to using a dedicated class for compression, an anonymous subroutine (aka CODEREF) may be used. In this case the calling syntax differs slightly: only the source and destination file names will be passed. The destination file naming rules apply as described for subclassing.

TODO

  • support numeric file modes and IO layers in open method

  • support other compression schemes (LZH, Bzip2, etc.)

BUGS

There are probably some lurking. I'm not entirely sure what would happen if you try to use one of Perl's more esoteric file opening styles such as "+>".

Pipes are also probably bad news.

AUTHOR

James FitzGibbon <jfitz@CPAN.org>

COPYRIGHT

Copyright (c) 2003, James FitzGibbon. All Rights Reserved.

This module is free software. You may use it under the same terms as perl itself.