【问题标题】:While loop does not read a file generated from code on PerlWhile 循环不读取从 Perl 上的代码生成的文件
【发布时间】:2017-03-20 02:58:16
【问题描述】:

我试图用我在 Perl 中的代码动态生成一个输出文件:

#!/usr/bin/perl 
use strict;
use Data::Dumper;
use warnings;  
use Bio::Seq;
use Bio::SeqIO; 
use Bio::DB::Fasta;
open my $OUT, "> ./temporal.gff";
           my $seq = $db->get_Seq_by_id($key);
            my $length  = $seq->length;
            my $all = $coord{$key};
            foreach my $keys (@$all[0]){
                    @sorted = sort { $a->[0] <=> $b->[0] } @$all;
                    $num = scalar @sorted;
                    my @new = &infer_gaps(\@sorted, $num, $length);
                    foreach my $ln (@new){
                            my @tmp = split /\s{2, }|\t/, $ln;
                            print $OUT "$key\tFillSequencer\tinference\t$tmp[0]\t$tmp[1]\t\.\t$tmp[2]\t\.\t$specie $key:$tmp[0]\-$tmp[1]\n";
                    }
                    #print Dumper \@new;    
            }
        }

但是,当我想使用这个生成的文件时,按照通常的方式使用while循环,它不会读取这个文件:

open my $ABC, "<./temporal.gff" or die $!;
    my $mRNA_seq;
    while (my $l = <$ABC>){
            chomp $l;
            my @arr = split /\t|\s+/, $l;
            #my $coor = $arr[0] . " " . $arr[3] . " " . $arr[4];
            $frame = $arr[6];
            my $final_seq = $db->seq( $arr[0], $arr[3], $arr[4] );
            my $output_nucleotide = Bio::Seq->new(
                    -seq => $final_seq,
                    -id  => $mRNA_name,
                    -display_id => $mRNA_name,
                    -alphabet => 'dna',
            );
            if ($frame eq '-') {
                    $output_nucleotide = $output_nucleotide->revcom();
            }
            $outfile_coor->write_seq($output_nucleotide);
    }

    close $ABC;

你有什么想法吗?当我使用 -d 标志运行我的代码时,它允许我确认代码跳过了最后一个 while 循环......我不知道 FILE HANDLE 变量的定义是否存在问题或任何其他不会生成的问题警告。提前致谢!

【问题讨论】:

  • 您忘记检查您的一些open 电话。看看use autodie。现已成为标准配置。
  • 是的!你是对的,解决方案是:关闭 $OUT,创建 out 文件的位置!非常感谢!

标签: perl while-loop file-handling


【解决方案1】:

我认为您需要在开始阅读之前关闭该文件。

或者,您可以刷新输出,以确保文件在开始读取之前已完全写入。

sub flush {
   my $h = select($_[0]); my $af=$|; $|=1; $|=$af; select($h);
}

# Flush immediately without turning auto-flush on:
flush($OUT);

有关如何使用冲洗的示例,请参阅此答案:

http://www.perlmonks.org/bare/?node_id=489962

【讨论】:

  • 关闭冲洗是多余的吗?它应该是关闭 还是 刷新?使用use IO::Handle; $OUT-&gt;flush; 也可以更好地处理冲洗。一旦IO::Handle 被加载,你可以在所有文件句柄上使用方法调用。
  • 文件输出默认是缓冲的,即使在关闭时也是如此。这样做是出于性能原因——文件写入是在操作系统空闲时完成的。刷新是确保它完全在磁盘上的唯一方法。
  • 不,close 也会刷新。来自 perldoc:“关闭与文件句柄关联的文件或管道,刷新 IO 缓冲区,并关闭系统文件描述符。
  • 好的,抱歉,我之前使用了flush来确保内容是一路写入的,所以如果程序死了,到目前为止所做的工作都会被保存。
  • 你甚至不再需要use IO::Handle; 来做$OUT-&gt;flush(或$OUT-&gt;autoflush)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-05
  • 2017-10-12
相关资源
最近更新 更多