Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Error binmode() on unopened filehandle

by RedJeep (Sexton)
on May 02, 2020 at 22:01 UTC ( #11116367=perlquestion: print w/replies, xml ) Need Help??

RedJeep has asked for the wisdom of the Perl Monks concerning the following question:

Hello. I am trying to convert an image to Base64. My environment is Windows 10, Perl 5.24.3

Thank you all in advance!

My code is...

use MIME::Base64; use strict; use warnings; my $upload_dir = 'uploaded_files'; my $file = 'image.jpg'; my $base64_a = ''; ### Open the image to convert to base64 open (IMAGE, "$upload_dir/$file") or die "$!"; binmode IMAGE; my $binary = do{ local $/ = undef; <IMAGE>; }; binmode $binary; $base64_a = encode_base64($binary); my $base64 = encode_base64(pack('B*', $binary)); print "base64 = $base64\n";

The funny thing is that it works but also kicks off an error.

The output is below... I truncated the Base64 output but this gives you an idea.

C:\inetpub\foto_root>test_binmode.pl binmode() on unopened filehandle at C:\inetpub\foto_root\test_binmode. +pl line 15, <IMAGE> line 1. base64 = oJwMowGRQNNgH8d24aQ2RsdiAAAAAAAAJLj8n+AVVkc4dN3p10iVUqqqqqqqp +VKpVKpVVVVU3/gV VmRYq3PyP5IelVVVVVVSqVSqVSqVSqVUZ1AAEGE3pUtAeRV1p247Xr9p2Guv7n9A9nOnOn +ZXdA42 pdQesc/9hOpZohX2DutSt/81SZ59Hb0FIO76iahG1+vNi8zyfmjNxSejvblU86wvDLZXRm +4ry0mW yua0S4Q90eqW7MYcDZcP4l9PBrvn+IDVzndz7jzr6Qdtxw8229DXCkbJBku40l+WPP3LWM +zb0n3R 1HH038+luuLCle7a0I1fbKViAAAbuACaCEXYx48/lGgW3nX3PuaVGfWYO6Hji+61TLusOy +q4VbUB yxV669JBpWOm9iflsw4PPuH19M39fAjGaXS9L5lTHpFLOgdiHgnWpHVBnhBcG1Ey7lUnsX +5m6E6a 7QvIKnZ4L/a6MrbXSao8wtaijRod4XP87X2ZlXqDVetDfQoJPWW2sWnVUfMUFeIYK3RVY+ +1kUolC ArLfmXFpHX/GYvYsydAm5e77Z9l6nO0v2Y3GjeNilVltW7uA0m1l42/tA7it9WBp2YC0RP +w86c8+

Replies are listed 'Best First'.
Re: Error binmode() on unopened filehandle
by stevieb (Canon) on May 02, 2020 at 22:16 UTC

    $binary is not a file handle. It's a normal scalar variable that you've stuffed the entire contents of the file into.

    Side note... you're best to use the three argument form of open(), and use a lexical file handle as opposed to a bareword global one:

    open my $fh, '<', 'file.ext' or die "Can't open file: $!"; while (<$fh>) { ... }
Re: Error binmode() on unopened filehandle (Path::Tiny slurp_raw)
by Anonymous Monk on May 02, 2020 at 23:09 UTC

    make life easier for yourself use Path::Tiny

    use Path::Tiny 'path'; my $data = path("foo.txt")->slurp_raw;
Re: Error binmode() on unopened filehandle
by Marshall (Canon) on May 03, 2020 at 13:49 UTC
    Once you go to BINMODE on a file handle, a record separator makes no sense.
    A more typical way to read a large binary file would be statements like this:
    binmode INBIN; my $n_bytes = read(INBIN, $buff, $BUFSIZE);
    That's a request to read $BUFSIZE bytes from INBIN into $buff. $n_bytes is number of bytes actually read from INBIN.
    I've never wound up reading a binary file in a single shot into a Perl variable because my bin files are not appropriate for that (so big they need to be read in chunks). However, I guess this would work (untested):
    use MIME::Base64; use strict; use warnings; my $upload_dir = 'uploaded_files'; my $file_name = 'image.jpg'; ### Open the image to convert to base64 open (IMAGE, '<', "$upload_dir/$file_name") or die "$!"; binmode IMAGE; my $binary = <IMAGE>; my $base64 = encode_base64(pack('B*', $binary)); print "base64 = $base64\n";
      Once you go to BINMODE on a file handle, a record separator makes no sense.

      Maybe you should have tested this.

      #!/usr/bin/perl use strict; use warnings; binmode DATA; my $binary = <DATA>; print "$binary\n"; __DATA__ first second
      This gives:
      first

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
        Ok, I tested with a .jpg file I had laying around.
        use warnings; use strict; open (my $fh, '<', "COVID19-Death02Apr.jpg") or die "$!"; binmode $fh; my $binary = <$fh>; #entire binary file goes to Perl variable print '',$binary;
        Works just fine!

        What you are overlooking is that you must set binmode before reading from the file. The Perl DATA file handle is an open file handle to the Perl program source that is seeked to the first character on the next line after __DATA__. This is buffered character mode I/O. You can't switch modes in the midst of a file.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11116367]
Approved by haukex
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2022-12-03 22:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?