Base64 MIME

B

Bigus

I am trying to convert a base64 encoded string in a plain text mailing list
archive file back into a document. I extract the string form the file and
then decode it like this:

open DC, ">$path/$filename";
print DC decode_base64($encoded);
close DC;

where $encoded is the base64 string.

It creates the file, say a jpg or doc, of what looks like about the right
size, but the images are corrupted. Is there anything obviously wrong with
this?

Bigus
 
B

Ben Morrow

Quoth "Bigus said:
I am trying to convert a base64 encoded string in a plain text mailing list
archive file back into a document. I extract the string form the file and
then decode it like this:

open DC, ">$path/$filename";

Use lexical filehandles.
Use three-arg open.
Check the return value of open.

open my $DC, '>', "$path/$filename"
or die "can't open '$path/$filename': $!";

If you are printing binary data to a filehandle you need to use binmode.
Yes, you need to use binmode on all platforms now.

binmode $DC;

If you don't care about compatibility pre-5.8, you can specify this as a
PerlIO layer in the open statement:

open my $DC, '>:raw', "$path/$filename"
or die "can't open '$path/$filename': $!";
print DC decode_base64($encoded);
close DC;

If you are worried about corruption or data loss, always check the
return value of close. If there is an error writing to the file (disk
full, network down, or whatever) it will show up here.

close $DC or die "writing to '$path/$filename' failed: $!";

Ben
 
J

John Bokma

Bigus said:
I am trying to convert a base64 encoded string in a plain text mailing
list archive file back into a document. I extract the string form the
file and then decode it like this:

open DC, ">$path/$filename";
print DC decode_base64($encoded);
close DC;

where $encoded is the base64 string.

It creates the file, say a jpg or doc, of what looks like about the
right size, but the images are corrupted. Is there anything obviously
wrong with this?

Wild guess: perldoc -f binmode
 
M

Mumia W. (reading news)

I am trying to convert a base64 encoded string in a plain text mailing list
archive file back into a document. I extract the string form the file and
then decode it like this:

open DC, ">$path/$filename";
print DC decode_base64($encoded);
close DC;

where $encoded is the base64 string.

It creates the file, say a jpg or doc, of what looks like about the right
size, but the images are corrupted. Is there anything obviously wrong with
this?

Bigus

It's probably writing the file in text mode which will corrupt a binary
file. Right after you open file file, use the binmode command to set the
file's mode to binary (AKA :raw).

Read the document for binmode:

Start->Run->"perldoc -f binmode"
 
B

Bigus

Ben Morrow said:
Use lexical filehandles.
Use three-arg open.
Check the return value of open.

open my $DC, '>', "$path/$filename"
or die "can't open '$path/$filename': $!";

If you are printing binary data to a filehandle you need to use binmode.
Yes, you need to use binmode on all platforms now.

binmode $DC;

thanks guys. binmode works a treat :)

WHat are the advantages of lexical filehandles and the 3-arg open?

Bigus
 
G

Gunnar Hjalmarsson

Ben said:
If you are printing binary data to a filehandle you need to use binmode.
Yes, you need to use binmode on all platforms now.

"Now"? Has something changed? In that case, where is that change documented?
 
C

Charlton Wilbur

GH> "Now"? Has something changed? In that case, where is that
GH> change documented?

In the past, printing binary data to files that did not have binmode
set often worked by accident. As soon as you introduce IO filters and
various encodings, that "by accident" is much less likely to happen.

The way to guarantee correct behavior is to use binmode when you are
printing binary data. That has not changed.

Charlton
 
B

Ben Morrow

Quoth Gunnar Hjalmarsson said:
"Now"? Has something changed? In that case, where is that change documented?

It changed as of 5.8. Pre-5.8 there was no need for binmode on Unix
systems and other systems whose stdio did not have the concept of 'text
mode' and never did CRLF-"\n" translation. This change is documented,
admittedly somewhat obliquely, in perl58delta.

Ben
 
G

Gunnar Hjalmarsson

Charlton said:
GH> "Now"? Has something changed? In that case, where is that
GH> change documented?

In the past, printing binary data to files that did not have binmode
set often worked by accident. As soon as you introduce IO filters and
various encodings, that "by accident" is much less likely to happen.

The way to guarantee correct behavior is to use binmode when you are
printing binary data. That has not changed.

Okay, thanks Charlton! I wondered, since at
http://perldoc.perl.org/functions/binmode.html it still says that it's
necessary "on some systems (in general, DOS and Windows-based systems)".
 
B

Bigus

Martijn Lievaart said:
Lexicals are scoped variables which are preferable over globals.


It's cleaner, clearer, safer and supports io-layers.

Yes, I suppose it is a bit.. just I've never seen it used before.

Regards
Bigus
 
B

Ben Morrow

Quoth (e-mail address removed) (Alan Curry):
In 5.6 binmode was explicitly documented as unnecessary on sane platforms:
Gradually, the documentation became less honest in its treatment of the
archaic systems. For example the correct and useful statement "modern
operating systems don't care" has been removed, making it officially
necessary to use binmode on files that are binary^H^H^H^H^H^Hnot text.

As of 5.8, it is necessary. Under some circumstances (in particular
5.8.0 in a UTF-8 locale: this default was removed in 5.8.1, but it is
easy to invoke it again) perl will expect files to be in UTF8, or to be
in the locale's character set, unless you specify they are 'not textual'
with binmode.
[A curse be upon whoever started the perverse usage of the word "binary" as
an antonym of "text", as if text files aren't stored in binary form by
computers too!]

They are, of course; but the point is that their binary representation
is not what one cares about. They are conceptually a sequence of
characters, and you don't care if they are stored as ASCII-with-LF,
ASCII-with-CR, ASCII-with-CRLF, EBCDIC, UTF8, or whatever. Perl and the
operating system conspire (not always successfully) to pretend that you
can read and write characters. If you *do* care about the octet-by-octet
content of a file, then you can say so by opening in in 'binary' mode.
As far as I can tell, there is no correct way under the new definitions to
handle files like (raw) PPM, which begins with a few lines of text and then
switches to non-text. Apparently you have to keep a copy of perl 5.005 around
if you want to handle those.

Well, since I sincerely doubt PPM's under DOS use CRLF line terminators
(or CR under Mac Classic), they are effectively 'binary' by Perl's
definitions, and you can read them perfectly well from a binmode :raw
filehandle. <> and the like work perfectly well for reading lines
defined however you choose from binary files.

Ben
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top