You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strawberry Perl 5.38.0.1输入文件流实时监控失效问题咨询

Perl 5.38实时读取文件更新失效的解决方法

问题原因

Perl 5.38调整了文件句柄的EOF处理逻辑:当读取到文件末尾(<$IN_STREAM>返回undef)后,后续的读取操作会直接返回undef,不会再重新检查文件是否有新增内容。而旧版本(5.32)中,即使到达EOF,后续读取仍会尝试从文件获取新数据,这导致了脚本行为差异。

解决方案

方法1:重置文件句柄的EOF标记

在检测到EOF后,通过seek操作重置文件句柄的EOF状态,让后续读取能重新检查文件内容:

#!/usr/bin/perl
use strict;
use warnings;

open(my $IN_STREAM, '<', 'file_in.txt') or die "Fail to open file_in.txt: $!";

while (1) {
    my $line = <$IN_STREAM>;
    if (defined $line) {
        print $line;
    } else {
        # 移动到当前位置,重置EOF标记
        seek($IN_STREAM, 0, 1);
        sleep(1);
    }
}

方法2:使用专门的文件跟踪模块File::Tail

File::Tail模块专为实时监控文件更新设计,能自动处理文件缓冲、EOF检测和内容新增读取,稳定性更高。先通过Strawberry Perl的cpanm安装模块:

cpanm File::Tail

然后编写脚本:

#!/usr/bin/perl
use strict;
use warnings;
use File::Tail;

# 初始化文件跟踪,maxinterval设置最长检查间隔(秒)
my $file_tail = File::Tail->new(name => 'file_in.txt', maxinterval => 1);

while (my $line = $file_tail->read) {
    print $line;
}

方法3:手动监控文件大小变化

通过定期检查文件大小,当文件变大时,读取新增的内容片段:

#!/usr/bin/perl
use strict;
use warnings;
use Fcntl qw(:seek);

my $filename = 'file_in.txt';
open(my $fh, '<', $filename) or die "Can't open $filename: $!";
my $current_size = -s $filename;

while (1) {
    my $new_size = -s $filename;
    if ($new_size > $current_size) {
        # 定位到上次读取的末尾位置
        seek($fh, $current_size, SEEK_SET);
        # 读取新增内容
        while (my $line = <$fh>) {
            print $line;
        }
        $current_size = $new_size;
    }
    sleep(1);
}

内容的提问来源于stack exchange,提问作者Jean-Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:32:42