Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
so I can identify a certain element by where it is in the file and modify it

If you know where the element is you will know its offset into the binary file. I think sysopen, sysseek, sysread and syswrite might be what you want. You are dealing with Vax shorts so your record length is two bytes. Numbering records from zero means that to get to a certain record you sysseek to a position in the file two times its record number. Then you can either sysread two bytes and unpack them to get the value or pack a new value and syswrite the packed two byte string.

Starting with the same binary file as before

$ hexdump -C spw1006361.bin 00000000 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 |......... +.......| 00000010 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f 00 |......... +.......| 00000020 10 00 11 00 12 00 13 00 14 00 15 00 16 00 17 00 |......... +.......| 00000030 18 00 19 00 1a 00 1b 00 1c 00 1d 00 1e 00 1f 00 |......... +.......| 00000040 $

Running this script

use strict; use warnings; use 5.014; use Fcntl qw{ :DEFAULT :seek }; use constant RECLEN => 2; my $binFile = q{spw1006361.bin}; sysopen my $binFH, $binFile, O_RDWR or die qq{sysopen: $binFile: $!\n}; my $origValue = readValue( $binFH, 7 ); say qq{Record 7 originally: $origValue}; writeValue( $binFH, 7, $origValue * 3 ); say qq{Record 7 now : @{ [ readValue( $binFH, 7 ) ] }}; close $binFH or die qq{sysopen: $binFile: $!\n}; sub readValue { my( $fh, $recNo ) = @_; sysseek $fh, $recNo * RECLEN, SEEK_SET or die qq{sysseek: $!\n}; my $bytesRead = sysread $fh, my $buffer, RECLEN; if ( not defined $bytesRead ) { die qq{sysread: $!\n}; } elsif ( $bytesRead == 0 ) { die qq{sysread: EOF\n}; } elsif ( $bytesRead != RECLEN ) { die qq{sysread: expected @{ [ RECLEN ] } bytes,}, qq{ got $bytesRead\n}; } else { return unpack q{v}, $buffer; } } sub writeValue { my( $fh, $recNo, $value ) = @_; sysseek $fh, $recNo * RECLEN, SEEK_SET or die qq{sysseek: $!\n}; my $bytesWritten = syswrite $fh, pack q{v}, $value; if ( not defined $bytesWritten ) { die qq{syswrite: $!\n}; } elsif ( $bytesWritten != RECLEN ) { die qq{syswrite: expected @{ [ RECLEN ] } bytes,}, qq{ wrote $bytesWritten\n}; } else { return; } }

Produces this output

]$ ./spw1006361 Record 7 originally: 7 Record 7 now : 21 $

The binary file now looks like this

]$ hexdump -C spw1006361.bin 00000000 00 00 01 00 02 00 03 00 04 00 05 00 06 00 15 00 |......... +.......| 00000010 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f 00 |......... +.......| 00000020 10 00 11 00 12 00 13 00 14 00 15 00 16 00 17 00 |......... +.......| 00000030 18 00 19 00 1a 00 1b 00 1c 00 1d 00 1e 00 1f 00 |......... +.......| 00000040 $

I hope this is heading in the right direction for you. Things will get more complicated if you want to delete records from the file or insert new ones but this functionality would not be too difficult to achieve.

Cheers,

JohnGG


In reply to Re^3: pack/unpack binary file by johngg
in thread pack/unpack binary file by mark4444az

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others scrutinizing the Monastery: (4)
    As of 2014-12-27 13:23 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Is guessing a good strategy for surviving in the IT business?





      Results (177 votes), past polls