In Perl, file handling is done by opening descriptors using open. Besides standard descriptors (STDIN, STDOUT, STDERR), you can create and manage your own.
Perl uses the concept of input-output layers (:encoding, :utf8, :raw, etc.) to correctly handle different types of files and encodings. By default, Perl can work in text mode (with newline conversion) or binary mode.
open my $fh, '<:encoding(UTF-8)', 'file.txt' or die $!; while (my $line = <$fh>) { print $line; } close $fh;
open my $fh, '<:raw', 'image.bin' or die $!; read($fh, my $data, -s 'image.bin'); close $fh;
Choosing the correct layer (:raw for binary, :encoding(NAME) for text) ensures proper reading and writing.
If you open a file using the statement
open FH, '<', $fileand read binary data, will we always get correct results?
Answer: No! Without specifying :raw, Perl on some platforms will automatically convert newline characters (e.g., CRLF → LF on Windows). Always use the :raw mode for reading binary files:
open my $fh, '<:raw', 'file.bin';
Story
In one corporate project, developers worked with text logs, reading lines without specifying the encoding. As a result, logs in UTF-8 sometimes "broke" — the read file was corrupted when reading Cyrillic characters because Perl misinterpreted the bytes. The issue was fixed only after explicitly adding the
:encoding(UTF-8)layer in theopencall.
Story
On Windows, when copying binary files, data were read using
open FH, '<', 'binfile.dat'and written without specifying the mode. The program "broke" images because in the newline stream CRLF was changed to LF, leading to invalid binary data. The:rawlayer fixed the issue.
Story
In an external API, STDOUT output was required to be in UTF-8, but programmers used
binmode STDOUT, ':encoding(UTF-8)', the problem was resolved.