Surprised by read()

M

Mark Wirdnam

Hello!

I've given this problem a weekend of consideration without conclusion.
I'm trying to use the "read"-command, for step-by-step reading from a
binary file. On my computer at work (Mac OS X, perl 5.6.0), the
scripts I write work. At home on Redhat Linux 8, perl 5.8.0, the same
scripts don't work - with the same files!
The symptoms are as if one read doesn't leave the file-pointer in the
right place for the second read, bytes are getting lost.

Here's an example of one such script:

open H, shift;
read H, $grab, 12;
($riff, $size, $wave) = unpack "A4VA4", $grab;

print "see whether it's a .wav: $riff - $size - $wave\n";
print "finding the chunks...\n";
$check = read H, $grab, 8;
while ($check == 8) {
($cid, $csize) = unpack "A4V", $grab;
print "finding a chunk $cid of size $csize.\n";
read H, $grab, $csize; # brings me to the next chunk
$check = read H, $grab, 8; }

Maybe you can see the mistake i'm making?

Thank you,
Mark
 
J

Jay Tilton

(e-mail address removed) (Mark Wirdnam) wrote:

: I've given this problem a weekend of consideration without conclusion.
: I'm trying to use the "read"-command, for step-by-step reading from a
: binary file. On my computer at work (Mac OS X, perl 5.6.0), the
: scripts I write work. At home on Redhat Linux 8, perl 5.8.0, the same
: scripts don't work - with the same files!
: The symptoms are as if one read doesn't leave the file-pointer in the
: right place for the second read, bytes are getting lost.

The distinction between characters and bytes is most likely the source
of trouble--Perl 5.8 is treating the file as a character stream, but
you want it as a byte stream.

binmode() acquired relevance on unix-like systems in Perl 5.8.
binmode() all filehandles containing binary data.
 
T

Tassilo v. Parseval

Also sprach Purl Gurl:
Mark Wirdnam wrote:

(snipped)



Are you creating these audio files under Macintosh and trying
to read them under Linux? There are significant differences
between Mac, Win32 and *Nix systems, pertaining to format and
syntax for various file type creation. Don't know having no Mac
for testing, but generating audio files under Mac, might be
the true source of your problem.

The difference between the formats of file types depends on their, well,
file type and not so much the operating system. A .wav file (more
precisely: a Microsoft PCM wave file) is defined to be little-endian.
That's the only thing that needs to be taken care of on Macintoshs since
they have big-endian byteorder.
Could not find anything in your script which would cause a
problem by transferring your script from Mac to Linux. This
would usually be a line ending problem, most often showing
up on a first line perl locale.

With a Win32 created wave file:

see whether it's a .wav: RIFF - 15148 - WAVE
finding the chunks...
finding a chunk fmt of size 50.
finding a chunk data of size 14983.


Actual file size is 15156 bytes as opposed to a returned 15148.

That's normal. The bytes 5 to 8 store the size of the file in bytes from
byte position 9 to the end. That's why the returned value is off by 8
from the actual file-size.

Tassilo
 
M

Mark Wirdnam

Thanks, I missed this vital information. It sounds like the likely
source of trouble. As soon as I can try this out, I'll post a short
feedback.

Indeed, that was the source of my problems. I can get my scripts to work now.
Mark
 
C

Charlton Wilbur

Purl Gurl said:
I am not so sure this is a beneficial change. Previously, no concern
was needed for binmode under nix environments. This never proved to
be a problem. Now it is a problem created by Perl porters.

As it happens, it's a problem created by wide characters, with the
Perl porters choosing the best solution to it.
At one time, filehandles could be binmode() to provide portability
for Win32 machines, a binmode call promptly ignored by nix machines.
With Perl 5.8, this portibility is lost, actually, all scripts will
now have to call binmode, in order to be portable with any machine.

In the past, binmode() was intended to be used whenever a distinction
between a text file and a binary file was made. As it happens, most
Unix programmers, realizing that at the time it was a no-op, omitted
it. This is now coming back around to bite them.

Charlton
 
A

Alan J. Flavell

As it happens, it's a problem created by wide characters, with the
Perl porters choosing the best solution to it.

My interpretation is that the _cause_ of the problem was those unix
bigots who kept pouring scorn on anyone who promoted the appropriate
use of binmode()
 
C

Chris Richmond - MD6-FDC ~

In the past, binmode() was intended to be used whenever a distinction
between a text file and a binary file was made. As it happens, most
Unix programmers, realizing that at the time it was a no-op, omitted
it. This is now coming back around to bite them.

Last time I checked, perl originated on Unix, and my handy dandy
copy of Programming Perl (2nd edition) clearly states in the binmode
description that "binmode has no effect under UNIX and Plan9."
So why would I ever bother to use binmode? The point is that
it didn't used to be a requirement and now it is, hence it
breaks lots and lots of existing scripts.

I don't usually build perl from scratch, but is there a compile
option to retain previous behaviour?

Chris
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top