binmode and <>

L

Larry

Is there any way to get "while (<>)" to use binmode? I can't figure it
out since binmode is supposed to be called after the file is already
open but before it is read for the first time, so you can't call it
before the loop, nor can you call it inside the loop.

I would also like to use binmode for 1-liners using -n or -p switches.
 
L

Larry

Larry said:
Is there any way to get "while (<>)" to use binmode? I can't figure it
out since binmode is supposed to be called after the file is already
open but before it is read for the first time, so you can't call it
before the loop, nor can you call it inside the loop.

I would also like to use binmode for 1-liners using -n or -p switches.

P.S. ... in case anyone is wondering why I would want to use <>
together with binmode (they usually don't go together) is that I have a
..csv file generated by Excel. Each record is terminated by "\r\n",
however inside each record there are some "\n" characters, representing
multi-line cells in the spreadsheet. So I want to set $/ = "\r\n" and
turn on binmode.
 
D

Dr.Ruud

Larry schreef:
Larry:

P.S. ... in case anyone is wondering why I would want to use <>
together with binmode (they usually don't go together) is that I have
a .csv file generated by Excel. Each record is terminated by "\r\n",
however inside each record there are some "\n" characters,
representing multi-line cells in the spreadsheet. So I want to set
$/ = "\r\n" and turn on binmode.

Try

perl -MO=Deparse -ne1

and you'll find the name of the handle.
 
J

John W. Krahn

Larry said:
Is there any way to get "while (<>)" to use binmode? I can't figure it
out since binmode is supposed to be called after the file is already
open but before it is read for the first time, so you can't call it
before the loop, nor can you call it inside the loop.

use open ':raw';

I would also like to use binmode for 1-liners using -n or -p switches.

perl -Mopen=:raw -pe'...'


perldoc open


John
 
L

Larry

Dr.Ruud said:
Larry schreef:

Try

perl -MO=Deparse -ne1

and you'll find the name of the handle.

I know the handle is ARGV, but knowing the name won't help. The handle
won't be open before the "while" loop so I can't "bindmode" it then.
Inside the "while" loop, it will already be too late to call "binmode",
since the line has already been read.
 
J

jl_post

Larry said:
Is there any way to get "while (<>)" to use binmode? I can't figure it
out since binmode is supposed to be called after the file is already
open but before it is read for the first time, so you can't call it
before the loop, nor can you call it inside the loop.

I would also like to use binmode for 1-liners using -n or -p switches.


Dear Larry,

A similar thread can be found at:

http://groups.google.com/group/comp...8559/aec888a9d829c0d7?&hl=en#aec888a9d829c0d7

Basically, it says that you can use the '-Mopen=IO,:raw' switch to
force your open() statements to open in binmode().

You can even use this with -n and -p switches. For example, if you
wanted to print out the number of bytes in every line of a file
'file.txt', you might write this:

perl -Mopen=IO,:raw -ne "print length" file.txt

(and it will report blank lines with DOS-line endings as having two
bytes, instead of just one.)

Oddly enough, the "perldoc open" documentation says that you can use
":bytes" instead of ":raw" for binary mode, but I haven't gotten that
to work (that is, it behaves exactly like I didn't use the
'-Mopen=IO,:bytes' switch at all). So either the documentation's
wrong, or there's a bug in my version of ActiveState Perl, or I'm not
doing something right.

Either way, I hope this helps, Larry.

-- Jean-Luc
 
D

Dr.Ruud

Larry schreef:
[perl -n, binmode]
I know the handle is ARGV, but knowing the name won't help. The
handle won't be open before the "while" loop so I can't "bindmode" it
then. Inside the "while" loop, it will already be too late to call
"binmode", since the line has already been read.


You might not need binmode().

C:\> perl -e "binmode STDOUT; print qq{AB\nCDE\nEFGH\r\n}" > bm.in

C:> debug bm.in
-d
14BB:0100 41 42 0A 43 44 45 0A 45-46 47 48 0D 0A xx xx xx
AB.CDE.EFGH..xxx
-q

C:\> perl -ne "print qq{ said:
<CDE
<EFGH

C:\> perl -ne "BEGIN{binmode STDOUT; $/=qq{\r\n}} print qq{<$_>}" bm.in
<AB
CDE
EFGH
 
D

DJ Stunks

Larry said:
I know the handle is ARGV, but knowing the name won't help. The handle
won't be open before the "while" loop so I can't "bindmode" it then.
Inside the "while" loop, it will already be too late to call "binmode",
since the line has already been read.

I think he meant you could binmode ARGV in a BEGIN block (untested) but
John's suggestion was, as usual, The Right Answer :p

-jp
 
J

jl_post

DJ said:
I think he meant you could binmode ARGV in a BEGIN block (untested) but
John's suggestion was, as usual, The Right Answer :p

I don't think you can binmode ARGV in a BEGIN block, because ARGV
isn't attached to any file before the first call of <>.

A quick test is this (on Win32 platforms):

If 'blah.txt' is a file that only contains one line (which is blank and
ends in a newline), we can verify that it contains two bytes with a
"DIR blah.txt" command.

Running the following perl one-liner:

perl -ne "BEGIN{binmode(ARGV)} print length" blah.txt

prints "1", meaning that it didn't properly read the two bytes as two
separate characters, since the binmode(ARGV) didn't "take."

But running the follong perl one-liner:

perl -Mopen=IO,:raw -ne "print length" blah.txt

prints "2", signifying that the ARGV filehandle is in binmode().

Incidentally, John's solution (which leaves off the "IO," part)
doesn't seem to work for me (I'm not sure why). When I type:

perl -Mopen=:raw -ne "print length" blah.txt

I get the following error:

Unknown PerlIO layer class ':raw' at -e line 0
BEGIN failed--compilation aborted.

(In case you're interested, I'm using Binary build 816 [255195]
provided by ActiveState -- Built Mar 1 2006 18:00:52.)
 
D

Dr.Ruud

(e-mail address removed) schreef:
Running the following perl one-liner:

perl -ne "BEGIN{binmode(ARGV)} print length" blah.txt

prints "1", meaning that it didn't properly read the two bytes as two
separate characters, since the binmode(ARGV) didn't "take."

With "warnings" activated:

$ perl -wne "BEGIN{binmode ARGV} 1" < /dev/null
binmode() on unopened filehandle ARGV at -e line 1.
 
J

John W. Krahn

But running the follong perl one-liner:

perl -Mopen=IO,:raw -ne "print length" blah.txt

prints "2", signifying that the ARGV filehandle is in binmode().

Incidentally, John's solution (which leaves off the "IO," part)
doesn't seem to work for me (I'm not sure why). When I type:

perl -Mopen=:raw -ne "print length" blah.txt

I get the following error:

Unknown PerlIO layer class ':raw' at -e line 0
BEGIN failed--compilation aborted.

The documentation states:

perldoc open
[ snip ]
These are equivalent

use open ’:utf8’;
use open IO => ’:utf8’;

as are these

use open ’:locale’;
use open IO => ’:locale’;

and these

use open ’:encoding(iso-8859-7)’;
use open IO => ’:encoding(iso-8859-7)’;


So the only thing I could think of was that this may have changed in a more
recent version.



John
 
J

John W. Krahn

John said:
But running the follong perl one-liner:

perl -Mopen=IO,:raw -ne "print length" blah.txt

prints "2", signifying that the ARGV filehandle is in binmode().

Incidentally, John's solution (which leaves off the "IO," part)
doesn't seem to work for me (I'm not sure why). When I type:

perl -Mopen=:raw -ne "print length" blah.txt

I get the following error:

Unknown PerlIO layer class ':raw' at -e line 0
BEGIN failed--compilation aborted.

The documentation states:

perldoc open
[ snip ]
These are equivalent

use open ’:utf8’;
use open IO => ’:utf8’;

as are these

use open ’:locale’;
use open IO => ’:locale’;

and these

use open ’:encoding(iso-8859-7)’;
use open IO => ’:encoding(iso-8859-7)’;


So the only thing I could think of was that this may have changed in a more
recent version.

It looks like it only recognises the 'utf8' layer:

$ perl -Mopen -le'print $open::VERSION'
open: needs explicit list of PerlIO layers at -e line 0
BEGIN failed--compilation aborted.
$ perl -Mopen=:raw -le'print $open::VERSION'
Unknown PerlIO layer class ':raw' at -e line 0
BEGIN failed--compilation aborted.
$ perl -Mopen=:bytes -le'print $open::VERSION'
Unknown PerlIO layer class ':bytes' at -e line 0
BEGIN failed--compilation aborted.
$ perl -Mopen=:utf8 -le'print $open::VERSION'
1.04
$ perl -Mopen=IO -le'print $open::VERSION'
1.04
$ perl -Mopen=IO,:raw -le'print $open::VERSION'
1.04



John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top