2012-12-19 15 views
8

Potrzebuję odczytać z pliku, iterować go i zapisać wiersz do innego pliku. Gdy liczba linii osiągnie próg, zamknij uchwyt pliku wyjściowego i otwórz nowy.W Perlu, jak uniknąć wielokrotnego otwierania plików

Jak uniknąć otwierania i zamykania uchwytu pliku wyjściowego za każdym razem, gdy czytam wiersz z uchwytu pliku wejściowego, jak poniżej?

use autodie qw(:all); 

my $tot  = 0; 
my $postfix = 'A'; 
my $threshold = 100; 

open my $fip, '<', 'input.txt'; 
LINE: while (my $line = <$fip>) { 
    my $tot += substr($line, 10, 5);  
    open my $fop, '>>', 'output_' . $postfix; 
    if ($tot < $threshold) { 
     print {$fop} $line; 
    } 
    else { 
     $tot = 0; 
     $postfix++; 
     redo LINE; 
    } 
    close $fop; 
} 
close $fip; 
+3

Nie otwieraj i nie zamykaj pliku wewnątrz pętli for. Przesuń komendę 'open' powyżej pętli for. –

Odpowiedz

11

Ponownie otwórz plik tylko po zmianie $postfix. Ponadto możesz uzyskać nieco prostsze.

use warnings; 
use strict; 
use autodie qw(:all); 

my $tot  = 0; 
my $postfix = 'A'; 
my $threshold = 100; 

open my $fop, '>>', 'output_' . $postfix; 
open my $fip, '<', 'input.txt'; 
while (my $line = <$fip>) { 
    $tot += substr($line, 10, 5);  

    if ($tot >= $threshold) { 
     $tot = 0; 
     $postfix++; 
     close $fop; 
     open $fop, '>>', 'output_' . $postfix; 
    } 
    print {$fop} $line; 
} 
close $fip; 
close $fop; 
+2

+1 ale myślę, że powinieneś zachować tylko drugą część swojej odpowiedzi. –

+0

I możesz dodać na dole: 'if (tell ($ fop)! = -1) {close $ fop; } ', aby je zamknąć. –

+4

Powinieneś zawsze sprawdzać błędy podczas otwierania plików. Chyba że używasz modułu 'autodie'. Który jesteś. :) – TLP

Powiązane problemy