我有一个文本文件,我读取第一行以了解它占用了多少字节,
open($fh, "<:raw", $file);
my $len;
while (my $row = <$fh>) {
$len = length $row;
last;
};
现在我想从文件的中间行开始读取+100个字节,我该怎么做?
类似这样:
read ($fh, 100, $len/2)
无法确切地理解正确的语法。
我有一个文本文件,我读取第一行以了解它占用了多少字节,
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;
在it技术中,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
将在$bytes_data
位置向$data
中写入。如果没有这个偏移量,每次读取都会覆盖$data
,可以将所有数据附加到字符串中(或以其他方式累积)。
虽然bytes::length
很好,但通常强烈不建议使用bytes pragma。
感谢ikegami的评论。
请注意,read
不会以任何特殊方式处理“换行符”,而读取可能会从文件的下一行(或多行)开始,而这些换行符字节确实计算,因此会影响您在文件中的位置。
未指定要执行的下一步操作,但可以保持(重新定位和)读取。
请参见此帖子,了解使用seek
和read
在文件中移动的清晰解释。
read
可能不会读取请求的那么多字节。需要使用循环。 - ikegamiseek
的最后一个参数(WHENCE
)使用命名常量。因此,请使用use Fcntl ':seek'
和seek $fh, $row_len/2, SEEK_SET
。 - Borodin:seek
标签)(2) 模块Fcntl加载了C语言的Fcntl.h
定义,这是一个用于处理文件描述符的标准实用程序(3) 这样,seek
可以使用fseek(3)
系统调用的命名常量(4) 这被广泛认为是良好的实践。 - zdimFcntl
文档,以欣赏该模块的实用性,并且对于fcntl
一般情况,只需在谷歌中输入并向下阅读即可。 - zdim