Работа с файлами
- FILEHANDLER - спец. тип
- STDIN, STDOUT, STDERR - спец. потоки
Открыть файл
open my $fh, '<', 'test.txt'; # '<' - открыть файл на чтение
print <$fh>; # <> - алиас для readline
Режимы открытия
<
- читать+<
- читать + писать(заменяет текущий текст) TODO: непонятно>
- писать+>
- писать + читать. TODO: непонятно>>
- дописать в конец. Читать не получиться
Указание кодировки при открытии
open my $fh, '<:encoding(CP-1251)', 'unicode.txt';
print <$fh>;
$ cat unicode.txt
�����
$ perl script.pl
Привет
Из cp-1251 в utf8
open my $fh_cp, '<:encoding(CP-1251)', 'unicode.txt';
open my $fh_utf, '>:encoding(UTF-8)', 'utf8.txt';
while ( <$fh_cp> ){
print $fh_utf $_;
}
close($fh_utf);
close($fh_cp);
$ cat unicode.txt
�����
$ cat utf8.txt
Привет
Чтение и запись в файл?
Читать можно из файла или из входного потока
my $input = <> # = <STDIN\> - чтение из дескриптора;
open my $fh, '<', 'test.txt';
my $input = <$fh>; # Первую строку
say $input;
my @input = <$fh>; # Или все строки
say @input; # Причем если прочитали то из файлхендлера удаляется!
$ perl script.pl
1
2
3
4
Писать также
open my $fh, '>', 'test.txt';
my $var = 'test';
print $var; # Пишет в STDOUT
print STDERR "ALARM!"; # Можно указывать явно поток
print $fh $var; # Пишет в файл
print {$fh} $var; # Можно и так
$ perl script.pl
ALARM!test
Выбор дескриптора
open my $fh1, '>', 'file1.txt' or die $!;
open my $fh2, '>', 'file2.txt' or die $!;
print "Написать в STDOUT\n";
select($fh1);
print "Написать в файл file1.txt\n";
my $old_fh = select($fh2); # можно выбрать и записать в переменную, причем сохраниться GLOB
print "Написать в файл file2.txt\n";
select(STDOUT);
print "Написать опять в STDOUT\n";
select($old_fh); # востановить предыдущий файлхендлер
print "Написать опять в файл file2.txt\n";
close $fh2;
close $fh1;
$ perl script.pl
Написать в STDOUT
Написать опять в STDOUT
$ tail -f file*
==> file1.txt <==
Написать в файл file1.txt
Написать опять в файл file2.txt
==> file2.txt <==
Написать в файл file2.txt
==> file1.txt <==
Втроенные данные
my @data = <DATA\>; # Здесь слеш не нужен!!
print @data;
__DATA__
Это текст который игнорирует перл, но может прочитать ;)
$ perl script.pl
Это текст который игнорирует перл, но может прочитать ;)
PS Чтобы прочитать, не нужно вызывать open
Функции для чтения
Для работы с двоичными данными. Не помю зачем нужно…
open my $fh, '<', 'test.bin' or die $!;
binmode($fh);
warn <$fh>;
Небуферизированная запись
open my $fh, '>', 'test.txt' or die $!;
my $data = "Test\n";
syswrite($fh, $data, length($data));
Прямой вызов системного вызова sysread. Ваще непонятно!
open my $fh, 'test.txt' or die $!;
my $data = "Test\n";
sysread($fh, $data, 2);
Чтение двоичных данных. TODO: нужен нормальный двоичный файл!
open my $fh, 'test.bin' or die $!;
my $data = "Test\n";
read($fh, $data, 2);
warn <$fh>;
Проверка на отсутствие данных в файле
open my $fh, 'test.txt' or die $!;
warn eof($fh);
my @test = <$fh>;
warn eof($fh);
$ perl script.pl
Warning: something's wrong at script.pl line 6.
1 at script.pl line 8, <$fh> line 1.
Пример
$ cat script.pl
#!/usr/bin/env perl
use strict;
use Digest::MD5 qw| md5_hex |;
$\ = "\n";
my $data = '';
my $data_size = 1024;
open my $fh, '<:raw', 'a.out' or die $!;
until ( eof($fh) ){
read($fh, $data, $data_size) == $data_size
or die "Неверный формат";
print md5_hex($data);
}
close($fh);
$ cat hi.cpp
#include <iostream\>
int main (){
std::cout << 123 << std::endl;
return 0;
}
$ g++ hi.cpp
$ perl script.pl
2912b5a9a1d612b3225e6259c8f16d82
2b4c581f784b0c9ec5541ebb18747f8c
4d158812ac0cf9d9b7788a148d2fb045
d7db69845df9d9aeea28d0aa03222594
7cad1fb5520ed9655e74d460d122f827
d63d4167a2bb47e5ff299d855de08437
fd05c1dde19ee23ae446b95029db2457
f11bd83a259b3f32e9076d03570a236e
Неверный формат at script.pl line 13.
ЗАЧЕМ???
Проверка результата работы программы open
open my $fh, 'Такого файла не существует!' || die $!;
$ perl script.pl
open my $fh, 'Такого файла не существует!' or die $!;
$ perl script.pl
No such file or directory at script.pl line 5.
Perl io backend
fread, fwrite - чтение из диска!
Взаимодействие с процессами
`` - бектике qw - синоним бектикетов exec - замена текущего процесса fork - порождение нового процесса pipe - связка манипуляторов в канал. Не сразу попадает в получателю! Но можно управлять через autoflush <> -> readline
$| = 1 -> autoflush на STDIN, STDOUT, STDERR - очистка буфера; Действует только на файлы! Если только на файл. $fh->autoflush;
waitpid - подождать когда завершаться chaild-ы
Модули
IPC::Open3
IPC::Run3
IO::Handle
Зомби
$? - 16
Обработка сигалов
{
local $SIG{INT} = 'IGNORE';
sleep 3;
}
warn "NOW";
sleep 10;
Локи на файлы
flock - работает только c flock
Сериализация
Почитать про pack и unpack pack и unpack могут быть разными!