seek FILEHANDLE,POSITION,WHENCE

设置 FILEHANDLE 的位置,就像 C stdiofseek(3) 调用一样。FILEHANDLE 可以是一个表达式,其值给出文件句柄的名称。WHENCE 的值是 0,将新位置以字节为单位设置为 POSITION;1 将其设置为当前位置加 POSITION;2 将其设置为 EOF 加 POSITION,通常为负数。对于 WHENCE,您可以使用 Fcntl 模块中的常量 SEEK_SETSEEK_CURSEEK_END(文件开头、当前位置、文件结尾)。成功返回 1,否则返回 false。

请注意对字节的强调:即使文件句柄已设置为对字符进行操作(例如使用 :encoding(UTF-8) I/O 层),seektellsysseek 函数族使用字节偏移量,而不是字符偏移量,因为在 UTF-8 文件中,查找字符偏移量会非常慢。

如果您想为 sysreadsyswrite 定位文件,请不要使用 seek,因为缓冲会使其对文件读写位置的影响不可预测且不可移植。请改用 sysseek

由于 ANSI C 的规则和严格性,在某些系统上,您必须在读写之间切换时执行 seek。除其他事项外,这可能会调用 stdio 的 clearerr(3)。WHENCE 为 1 (SEEK_CUR) 用于不移动文件位置

seek($fh, 0, 1);

这对于模拟 tail -f 的应用程序也很有用。当您在读取时遇到 EOF 然后休眠一段时间后,您(可能)必须插入一个虚拟 seek 来重置事物。 seek 不会改变位置,但它确实清除了句柄上的文件结束条件,因此下一个 readline FILE 使 Perl 再次尝试读取内容。(我们希望如此。)

如果这不起作用(某些 I/O 实现特别固执),您可能需要类似以下内容

for (;;) {
    for ($curpos = tell($fh); $_ = readline($fh);
         $curpos = tell($fh)) {
        # search for some stuff and put it into files
    }
    sleep($for_a_while);
    seek($fh, $curpos, 0);
}