in reply to Re: Mysteries of unpack("a", ...)
in thread Mysteries of unpack("a", ...)

I am not at all sure that STDIN can even be opened in binary mode at all!

Yes it works the same on STDIN as other handles. Specifically, it disables crlf→lf conversion on Windows machines, it stops treating chr(26) as the end of file on non-PerlIO Windows builds, and does nothing elsewhere.

I mean CTL-C, CTL-Z mean things to STDIN although these are certainly valid binary values.

No they don't. They may mean something to the tty/console, but STDIN doesn't even know about the Ctrl key. It doesn't treat character 3 or 26 specially.

>perl -e"print qq{\x03\x1A}" | perl -le"print uc unpack 'H*', <STDIN>" 031A $perl -e'print qq{\x03\x1A}' | perl -le'print uc unpack "H*", <STDIN>' 031A

If you want to read binary data, open a file in binmode... local $/ = undef; is not needed.

Not true at all. $/ is quite useful on binary files.

my @records = map parse_rec($_), map /(.{$RECSIZE})/sg, do { local $/; <$fh> };

and

my @records; local $/ = \$RECSIZE; local *_; while (<$fh>) { push @records, parse_rec($_); }

are equivalent to

my @records; local *_; while (read($fh, $_, $RECSIZE)) { push @records, parse_rec($rec); }

Mind you, read is unaffected by $/, but that has nothing to do with whether the file is binary or not.

Replies are listed 'Best First'.
Re^3: Mysteries of unpack("a", ...)
by Marshall (Canon) on Jan 03, 2009 at 17:09 UTC
    I use STDIN for command line filters of "catable files" (text), eg. cat or "type" in the Windows world can display those files. I stand corrected about use of a binary file for such a purpose.

    I am curious as to what "*_" means? I couldn't find that in my reference books.

    The kind of binary files I usually deal with might have an odd number of bytes and I have to fix it up in the final result with either 16 bit aligned or 32 bit aligned values. Sometimes that means shifting things over a byte or more, So something like:
    my $n_bytes = read(INBIN, $buff, $BUFSIZE); is the ticket. Your mileage may vary as they say! I haven't written any really hairy binary stuff in Perl.

      *_ is the symbol table entry (glob) containing $_ (and @_, %_, etc). Using local on globs is safer than using local on scalars.

      I don't know why you are trying* to prove that read can do something <> can't. I didn't say you shouldn't use read. I didn't say it was useless. I didn't say <> can do everything read can.

      * — You haven't come up with something yet. Keep in mind that length($buff) also returns the number of bytes read.