2009-04-09

Neat Trick

Sometimes when I can't sleep, I swallow a handful of pills and surf the Internet for hours on end until they start to kick in. Other times, I write software. Sometimes I do both.

One of the more esoteric problems with UNIX and its variants is that in order to write to something, you usually end up having to read from something. For 99% of what most people need to do, this fits the bill. Yet every so often, a weird kind of case crops up where what your files look like don't matter so much as where they are and how big they seem.

Log rotation testing, for example, doesn't need real logs. It just needs files of certain sizes with certain modification times in certain places on your disk.

ThreeFour years ago (oh God I'm getting old) I discovered a neat trick in .NET that lets you fiddle with the filesystem metadata without having to loop through a device like /dev/zero with dd in order to make files of arbitrary sizes. With the advent of PowerShell, this makes arbitrary filesizing a snap on Windows:

PS C:\> $fs = New-Object System.IO.FileStream "test.txt", "OpenOrCreate"
PS C:\> $fs.SetLength(1234567)
PS C:\> $fs.Close()
PS C:\> get-item "test.txt" | Format-List -Property Length

Length : 1234567

This is much faster than doing it with dd, or with Perl:

open( my($fh), "> test.txt") or die;
  my $count = 0;
  while( $count < 1234567 ) {
    print $fh chr( 65 + int rand(62)); # fill with random characters
    $count++;
  }
close($fh);

Note that use of the FileStream.SetLength() method will not fill your new arbitrarily-big files with meaningful (or even safe) data. This makes the technique rubbish for any kind of realistic compression testing. If you were going to try to use this to play with lzop then you might want to stick to the Perl approach. There is of course a PowerShell equivalent to that too, but damned if I've looked into it yet.

No comments: