sysseek

sysread や syswrite で扱われるファイルハンドルのポインタ移動する

構文

解説

sysseek は、FILEHANDLE のファイルポインタをバイト位置でセットします。 POSITION はバイト数による位置を表しますが、バイトをどこから数えるのかを WHENCE で指定します。 0 ならファイルの先頭から数えます。1 なら現在のファイルポインタの位置から数えます。 2 ならファイルの最後から数えます。しかし、逆方向に数えなければならないため、POSITION には負の値を指定します。

次の例は、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;

Fcntl モジュールを使うと、 WHENCE に定数 SEEK_SET (0), SEEK_CUR (1), SEEK_END (2) を使うことができます。

use Fcntl 'SEEK_SET';
sysseek $fh, 6, SEEK_SET;

sysseek は新しいファイルポインタの位置を返します。 ファイルポインタの移動に失敗した場合は undef を返します。 もし新しいファイルポインタの位置が 0 (ファイルの先頭) の場合、文字列 "0 but true" が返されます。 これによって、たとえファイルポインタがファイルの先頭だったとしても、戻り値を ifunless で評価して、 sysseek の処理の成否判定を行うことができます。

sysseek は、sysread および syswrite によるファイル操作で使います。 read, readline, write, seek, tell, eof と組み合わせて使うことがないよう注意してください。