Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Byte ranges of binary files

by PearlsOfWisdom (Initiate)
on Jul 27, 2013 at 14:50 UTC ( #1046653=perlquestion: print w/ replies, xml ) Need Help??
PearlsOfWisdom has asked for the wisdom of the Perl Monks concerning the following question:

Greetings oh wise ones, Is this the correct/most efficient way of grabbing a range of bytes from a file ? I get this funny feeling the use of "do" might come back to haunt me ?
my $myRange = $rangeEnd - $rangeStart; seek($fh,$rangeStart,0); my $currentIncrement=0; my $numberOfIncrements = $myRange / $readSz; do { $n1 = read($fh, $buf1, $readSz); # DO STUFF WITH $buf1 # $currentIncrement++; } until !defined($n1) || $n1 == 0 || $currentIncrement==$numberOfIncre +ments;

Comment on Byte ranges of binary files
Download Code
Re: Byte ranges of binary files
by BrowserUk (Pope) on Jul 27, 2013 at 15:01 UTC
    Is this the correct...

    $myRange  ne  $readSz?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      The idea in my brain was that $myRange = the range of bytes required, and $readSz = the buffer size. But maybe that got lost in translation into Perl ?

        You could try something like:

        use constant READSIZE => ...; my $fh = ...; my $start = ...; my $end = ...; ## check $end < -s($fh)! seek $fh, $start, 0; while( ($_ = tell( $fh ) ) < $end ) { local $/ = \min( READSIZE, $end - $_ ); my $chunk = <$fh> or die $!; ## ... }

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Byte ranges of binary files
by RichardK (Priest) on Jul 27, 2013 at 15:40 UTC

    What if your range isn't a whole number of $readsz chunks?

    I'd do something like this :-

    while ($myrange) { $myrange -= read($fh, $buf, min($myrange,$readsz) ) or last; # do stuff }
      > What if your range isn't a whole number of $readsz chunks? Shows the use of a second pair of eyes ! Thank you ! ;-) Will go try ....
      Question... doesn't last stop the processing prematurely before the rest of the while block gets a chance to execute ?

        No.

        what do you think the 'or' is doing in that statement?

        hint: Have a look at at 'logical or' in perlop

Re: Byte ranges of binary files
by zork42 (Monk) on Jul 28, 2013 at 05:19 UTC
    (1) For portability, remember to put the file into binmode immediately after opening it.

    (2) Also, do you have an off-by-1 error?
    Should
    my $myRange = $rangeEnd - $rangeStart;
    actually be
    my $myRange = $rangeEnd - $rangeStart + 1; ^^^
    ?

      Re: Also, do you have an off-by-1 error? Hmm .... I spend hours on end staring at my computer screen and trying all the examples posted here and I still couldn't get the program to work like I think it should be. ;-(

      Perhaps I'll go back to my initial code and try with the amended range. Will let you know how it goes.

Re: Byte ranges of binary files
by zork42 (Monk) on Jul 29, 2013 at 04:54 UTC
    How about this?

    NB untested
    use strict; use warnings; use autodie; my $filename = '...some filename...'; my $rangeStart = 10_000; my $rangeEnd = 20_000; open my $fh, "<", $filename; binmode $fh; seek($fh, $rangeStart, 0); my $total_bytes_to_read = $rangeEnd - $rangeStart + 1; my $buffer_size = 1_024; my $buffer; my $num_bytes_to_read; my $num_bytes_actually_read; # read() : Returns the number of characters actually read, 0 at end of + file, or undef if there was an error (in the latter case $! is also +set) while ( ( $num_bytes_to_read = ($buffer_size <= $total_bytes_to_re +ad) ? $buffer_size : $total_bytes_to_read ), # handle partial buffer ( $num_bytes_actually_read = read($fh, $buffer, $num_bytes +_to_read) ), ( (defined $num_bytes_actually_read) && ($num_bytes_actual +ly_read > 0) ) ) { $total_bytes_to_read -= $num_bytes_actually_read; # process $num_bytes_actually_read in $buffer } if ( ! defined $num_bytes_actually_read ) { die $! } # there was an +error. In this example, autodie will detect this, but # + without autodie you'd need to check it yourself. ( $num_bytes_actually_read == 0 ) || die "Should never happen"; # if $total_bytes_to_read > 0, then reached EOF before reading all spe +cified data # ie $rangeEnd > size of $filename

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1046653]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2014-08-01 23:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who would be the most fun to work for?















    Results (51 votes), past polls