从文件中读取 n 个字节的文本

Read n bytes of text from file

我有一个文本文件,我读取了它的第一行以了解它占用了多少字节,

open($fh, "<:raw", $file);
my $len;
while (my $row = <$fh>) {
  $len = length $row;
  last;
};

现在我想从中间行读取该文件 +100 字节,我该怎么做?

类似于

read ($fh, 100, $len/2)

无法真正找出正确的语法。

得到线的长度后

my $row_len = length <$fh>;  # with newline, or (read then) chomp first

使用 seek

将把手放在您需要的位置
use Fcntl qw(:seek);

seek $fh, $row_len/2, SEEK_SET;

其中 Fcntl 提供常量 SEEK_SETSEEK_CURSEEK_END,以便第二个参数中的位置取自开头或当前位置, 或文件结尾(当通常使用负数位置时)。可以使用 012.

而不是这些

然后使用read

$bytes读入$data
my $bytes = 100;
my $data;

my $rb = read $fh, $data, $bytes;

其中 $rb 是实际从请求的 $bytes 中读出的字节数。


对于某些文件句柄(一个套接字)read 可能不会立即获得请求的那么多,因此您需要继续阅读。例如,使用 OFFSET (参见文档)写入字符串

use bytes qw();

my ($data, $requested, $total_read) = ('', 100, 0); 

while ($total_read < $requested) {
    my $bytes_data = bytes::length $data;
    $total_read += read $fh, $data, $requested - $bytes_data, $bytes_data;
}

其中 read 现在写入位置 $bytes_data$data。如果没有这个偏移量,每次读取都会覆盖 $data,什么可以附加到包含所有数据(或以其他方式累积)的字符串。

虽然 bytes::length 很好,但 bytes pragma 通常“ 强烈建议不要使用 ”。


感谢 ikegami 的评论。

请注意,read 不会以任何特殊方式处理“换行符”,并且读取很可能会从文件的下一行读取,而那些换行符字节确实计数,因此影响你在文件中的位置。

未指定下一步要做什么,但您可以继续(重新定位和)阅读。

请参阅 this post 以了解 crystal 使用 seekread.

在文件中移动的清晰解释