vinforget has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I have a file of known length and content (basically just a one line descriptor and a string of 1's and 0's:
descriptor
10101010000101011110101010101010101010
Access to the bits is quite easy since I just calculate the offset of the descriptor line when using seek. However, is there a way that i can access a particular "bit" and change it? I am familiar with "read" and "seek", but I don't know if I can "write" using the same techniques. I would also like something that is not memory intensive. These files can get somewhat large (250Mb).Thanks
Vince
  • Comment on random read wite access to a fixed file

Replies are listed 'Best First'.
Re: random read wite access to a fixed file
by BrowserUk (Patriarch) on Nov 16, 2004 at 22:26 UTC

    Open the file RW ('+<'. See perlopentut for more info.)

    Use sysseek to move to the byte ("bit") of interest.

    Use syswrite (syswrite FH, $bitvalue, 1;) to write the "bit" in question.

    #! perl -slw use strict; use Fcntl qw[ SEEK_SET SEEK_CUR SEEK_END ]; open OUT, '> :raw', 'test.dat' or die $!; print OUT 'descriptor'; print OUT '1' x 1000; close OUT; my $descOffset = length( 'descriptor' ) + 2; ## May vary with OS defin +ition of "\n"; open RW, '+< :raw', 'test.dat' or die $!; for( my $bitPos = 0,; $bitPos < 1000; $bitPos += 2 ) { ## Read bit[ $bitPos ] sysseek RW, $descOffset + $bitPos, SEEK_SET; my $bit; sysread RW, $bit, 1; print "bit[ $bitPos ] = $bit"; ## Update bit[ $bitPos ] sysseek RW, $descOffset + $bitPos -1, SEEK_SET; ## -1 gives zero-based bit positions. syswrite RW, '0', 1; } close RW;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: random read wite access to a fixed file
by jZed (Prior) on Nov 16, 2004 at 22:23 UTC
    If you want to write at the end of the file, just seek there and write. If you want to write somewhere else in the file and you are going to write exactly the same length of data as you are replacing, seek there and write. If you are going to be inserting, rather than replacing, you'll need to either dump to a backup and re-write the whole file, or dump into memory, seek to the begining, truncate, the file, dump back from memory and save.
      Yes, I plan to repleace the same length of data as i intend to write i.e. just changing the 0 or 1 to a 1 or 0.
      Thanks for the help.
      Vince