我有一个文本文件,我从中读取第一行,找出它需要多少字节,
open($fh, "<:raw", $file);
my $len;
while (my $row = <$fh>) {
$len = length $row;
last;
};
现在我想从中间行+100字节读取该文件,我该怎么做?
像
这样的东西read ($fh, 100, $len/2)
无法弄清楚正确的语法。
答案 0 :(得分:6)
获得行长
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_SET
,SEEK_CUR
和SEEK_END
,以便第二个参数中的位置取自开头或当前位置,或者文件的结尾(通常使用负位置时)。而不是这些可以使用0
,1
,2
。
然后使用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
现在写入位置$data
的{{1}}(否则每次都会覆盖)。另一种方法是将每个读取附加到包含所有数据的字符串;然后应该没有偏移。
虽然$bytes_data
很好,但bytes pragma一般都是&#34; 强烈反对&#34;。
感谢ikegami的评论。
请注意,bytes::length
并未处理&#34;换行符&#34;以任何特殊方式读取可能会从文件的下一行中获取,而这些换行字节确实会计数,从而影响您在文件中的位置。
未指定您接下来要做什么,但您可以保留(重新定位和)阅读。
有关使用read
和seek
移入文件的清晰说明,请参阅this post。