antiquark:
Several things:
- I've never use Storable before, but by reading the documentation, I'd expect that if the stuff at the end is the problem (and I don't think it is), then you could solve it by replacing your seek with closing the file and reopening it in write mode.
- However, since it appears (also from the docs) that you can store and retrieve multiple objects from the file descriptor, having extra stuff at the end shouldn't be a problem, as the file format should be able to handle the end of an object with more stuff after it. You aren't trying to read multiple objects from the stream in any order you please, are you? If so, I'd expect extra seeks and reads to be problematic, as you could skip over any bookkeeping information Storable may use.
- The docs also mention that the store functions have versions with an 'n' prefix to use network order. You're not using your stored data between machines are you? If so, you may want to use the 'n'-prefixed versions to ensure you're not being bitten by an endianness bug between CPUs.
OK... now that I've said that, I've gotten curious. I just kicked out a quickie example:
#!/usr/bin/perl
use strict;
use warnings;
my %hsh = ( Apple=>1, Banana=>7, Cherry=>42 );
my $txt = "The quick red fox jumped over the lazy brown dog";
my @ary = (17, 'Flugelhorn', 13.333);
use Storable qw( nstore_fd );
open my $SF, '>', 'tst_Storable.db' or die "Error: $!\n";
nstore_fd \%hsh, $SF;
nstore_fd \$txt, $SF;
nstore_fd \@ary, $SF;
close $SF;
That writes some variables to the test file, and now to read and display the data:
#!/usr/bin/perl
use strict;
use warnings;
my %hsh;
my $txt;
my @ary;
use Storable qw( fd_retrieve );
open my $SF, '+<', 'tst_Storable.db' or die "Error: $!\n";
%hsh = (%{fd_retrieve $SF});
$txt = ${fd_retrieve $SF};
@ary = @{fd_retrieve $SF};
close $SF;
print "Text: '$txt'\n";
print "Array: (", join(', ', @ary), ")\n";
print "Hash: (", join(', ', map { "$_=>$hsh{$_}" } keys %hsh), ")\n";
So when I run it, I get the expected results:
roboticus@Boink:~
$ perl tst_Storable_2.pl
Text: 'The quick red fox jumped over the lazy brown dog'
Array: (17, Flugelhorn, 13.333)
Hash: (Cherry=>42, Banana=>7, Apple=>1)
You can definitely store multiple objects with Storable, so once you read an object, it shouldn't matter that there's extra data. So I'm guessing that either you need to:
- binmode your handle, as suggested by ikegami, or
- add the 'n' prefix for inter-machine usage, or
- stop seeking around in the file (if that's what you're doing).
Personally, I think I'd just use "read" mode to read all the objects, and at the end of the program, open in "write" mode to store everything. The fact that you're using read/write leads me to suspect that you may be seeking around the file reading and writing objects and confusing Storable so it can't keep track of the state of the objects since its bookkeeping information isn't where it expects to find it.
If that's what you're doing, then an ugly hack may be to write a sentinel value after (and possibly before) every value you may want to read randomly. That way, writing the sentinel may give Storable enough bookeeping information about the end of the object (if that's what it's lacking).
...roboticus
|