Hello, Monks !

I'm relatively new to Perl and still in a phase of learning how things work. My question might sound stupid to you but I searched perldoc back and forth and googled through the web (including your great site) without finding an answer. So here's my question:

Short version: How do I portably and correctly open() a binary file ?


Long version or how I got all confused about that:

My PerlIO documentation states the following about the ":raw" layer:

The ":raw" layer is defined as being identical to calling "binmode($fh)" – the stream is made suitable for passing binary data i.e. each byte is passed as-is. The stream will still be buffered.

Having read that I thought the following two code fragments would be equivalent:

open(my $fh, '<', $filename); binmode($fh);
open(my $fh, '<:raw', $filename);

Because the second one is shorter (and I only have to check one function return value) I used that method in some scripts.

So far so good. A couple of days ago I discovered the PerlIO::get_layers() function and curious and naiv as I am I did the following:

$, = ' '; $\ = "\n"; open(FH, '<', '/dev/null'); print(PerlIO::get_layers(FH)); # --> unix perlio

As documented and expected this is the default layer stack on an UNIX system.

open(FH, '<', '/dev/null'); binmode(FH); print(PerlIO::get_layers(FH)); # --> unix perlio

So is this one. No problems yet, but look at the next one:

open(FH, '<:raw', '/dev/null'); print(PerlIO::get_layers(FH)); # --> unix

Big surprise (at least for a dummy like me): The ":perlio" layer mysteriously disappeared. And this mystery is the whole reason for this post.

Obviously, using ":raw" in open() is not the same as calling binmode() afterwards. Having no ":perlio" layer also means that the stream is unbuffered now, right ? (Which explains the results of this PerlIO Benchmark, which I found while searching for answers.)

Btw., My perl version is v5.8.4 but a friend of mine just confirmed the last code snippet on perl version v5.8.8.

Could someone please explain to me what I misunderstood so badly here. (Need not be a lengthy answer, a link or a hint to the right place in some Perl documentation would suffice.)

Thanks so much !


In reply to Using ":raw" layer in open() vs. calling binmode() by Anonymous Monk

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!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • 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, details, 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, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            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.