Perl CookbookPerl CookbookSearch this book

11.10. Reading and Writing Hash Records to Text Files

11.10.1. Problem

You want to read or write hash records stored in text files.

11.10.2. Solution

Use a simple file format with one field per line:

FieldName: Value

and separate records with blank lines.

11.10.3. Discussion

If you have an array of records that you'd like to store into and retrieve from a text file, you can use a simple format based on mail headers. The format's simplicity requires that the keys have neither colons nor newlines, and the values not have newlines.

This code writes them out:

foreach $record (@Array_of_Records) {
    for $key (sort keys %$record) {
        print "$key: $record->{$key}\n";
    }
    print "\n";
}

Reading them in is easy, too.

$/ = "";                # paragraph read mode
while (<>) {
    my @fields = split /^([^:]+):\s*/m;
    shift @fields;      # for leading null field
    push(@Array_of_Records, { map /(.*)/, @fields });
}

The split acts upon $_, its default second argument, which contains a full paragraph. The pattern looks for start of line (not just start of record, thanks to the /m) followed by one or more non-colons, followed by a colon and optional whitespace. When split's pattern contains parentheses, these are returned along with the values. The return values placed in @fields are in key-value order, with a leading null field we shift off. The braces in the call to push produce a reference to a new anonymous hash, which we copy @fields into. Since that array was stored in order of the needed key-value pairing, this makes for well-ordered hash contents.

All you're doing is reading and writing a plain text file, so you can use related recipes for additional components. You could use Recipe 7.18 to ensure that you have clean, concurrent access; Recipe 1.18 to store colons and newlines in keys and values; and Recipe 11.3 to store more complex structures.

If you are willing to sacrifice the elegance of a plain textfile for a quick, random-access database of records, use a DBM file, as described in Recipe 11.14.

11.10.4. See Also

The split function in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 11.9; Recipe 11.13; Recipe 11.14



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.