sysread

ファイルハンドルから固定長の未バッファデータを取り出す

構文

解説

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 を指定すると、引数 SCALAROFFSET の位置から読み取ったデータを上書きします。 OFFSET は、ファイルハンドルの読み取り開始位置ではないので注意してください。

もし OFFSET が 3 なら、SCALAR の先頭から 3 バイトはそのままに、 それ以降の 4 バイト目から置換されます。

もし OFFSETSCALAR のバイト長より大きい場合、 SCALAR の空いた部分は \0 で埋められます。

sysread と良く似た組み込み関数に read がありますが、 その違いは PerlIO レイヤーを通さないか通すかです。 もし読み取ったデータを文字として扱いたい場合は read を使うのが良いでしょう。

なお、Perl 5.30 以降は、:utf8 ハンドルで sysread を使うと 例外を投げますので注意してください。 [perldeprecation]

open my $fh, '<:utf8', './sample.txt';
sysread $fh, my $str, 6;    # エラーになる