ファイルハンドルから固定長の未バッファデータを取り出す
sysread
は、ファイルハンドル FILEHANDLE を、現在のファイルポインタの位置から LENGTH 分のバイト数だけ読み取って、
そのデータをスカラー変数 SCALAR にセットします。
そして、sysread
は、実際に読み取ったバイト数を返します。
もし何かしらのエラーが発生したなら undef
が返されます。
その場合、そのエラー内容は $! にセットされます。
次の例は、JPEG 形式の画像ファイルを読み込んで、SOI (スタートマーカー) をチェックしてから、JPEG フォーマットを判定します。
open my $fh, '<', './sample.jpg';
# SOI (スタートマーカー)
sysseek $fh, 0, 0; # 先頭から 0 バイトの位置にファイルポインタを移動
sysread $fh, my $soi, 2; # 2 バイト読み取る
unless ( unpack( 'H4', $soi ) eq 'ffd8' ) {
die "JPEG ファイルではありません。";
}
# JPEG フォーマット
sysseek $fh, 6, 0; # 先頭から 6 バイトの位置にファイルポインタを移動
sysread $fh, my $fmt, 4; # 4 バイト読み取る
my $fmtname = unpack( 'a4', $fmt ); # "JFIF" または "Exif"
print "JPEG フォーマットは ${fmtname} です。";
close $fh;
sysread
に引数 OFFSET を指定すると、引数 SCALAR の
OFFSET の位置から読み取ったデータを上書きします。
OFFSET は、ファイルハンドルの読み取り開始位置ではないので注意してください。
もし OFFSET が 3 なら、SCALAR の先頭から 3 バイトはそのままに、 それ以降の 4 バイト目から置換されます。
もし OFFSET が SCALAR のバイト長より大きい場合、
SCALAR の空いた部分は \0
で埋められます。
sysread
と良く似た組み込み関数に read
がありますが、
その違いは PerlIO レイヤーを通さないか通すかです。
もし読み取ったデータを文字として扱いたい場合は read
を使うのが良いでしょう。
なお、Perl 5.30 以降は、:utf8
ハンドルで sysread
を使うと
例外を投げますので注意してください。
[perldeprecation]
open my $fh, '<:utf8', './sample.txt';
sysread $fh, my $str, 6; # エラーになる