2011-09-22 28 views
5

Piszę do dwóch plików, jeden dziennik za pomocą funkcji Log_message, a drugi w mojej funkcji zapisu pliku do OUT i chcę napisać wiersz po linii i nie być buforowany, aby zapisywać wiersz po wierszu, a nie wszystkie w jeden idzie na końcu skryptu.

Przeczytałem o buforowaniu i tworzeniu gorącego pliku, ale nie mogę uruchomić mojego kodu.

W tym przykładzie dodałem $|=1; tuż przed pętlą foreach, ale wciąż pisze za jednym zamachem. Czy robię coś naprawdę głupiego?

Załączam cały mój skrypt, jeśli to pomaga.

#----------------------------------------------- 
    sub file_write { 
    #----------------------------------------------- 
    open OUT, ">>$OUT" or Log_message ("\n$DATE - $TIME - ERROR - Could not create filelist.doc \t"); 
    Log_message ("\n$DATE - $TIME - INFO - Opened the output file"); 
    my $total = scalar keys %{ $doc->{ resource } }; 
    Log_message ("\n$DATE - $TIME - INFO - Found: " . $total . " resources"); 
    #printf "resources: %s\n", scalar keys %{ $doc->{ resource } }; 

    $|=1; 

    #And I have also tried: 

    #use IO::Handle; 
    #STDOUT->autoflush(1); 

    foreach (keys %{ $doc->{ resource } }) { 
     #print OUT $doc->{ resource }->{ $_ }->{ id }, "\n"; 
     my $ID = $doc->{ resource }->{ $_ }->{ id }, "\n"; 
     Log_message ("\n$DATE - $TIME - INFO - Found: " . $ID); 
     my $testurl = "http://dronlineservices.letterpart.com/web/content.xql?action=doc_html&lang=en&pub=" . $pubId . "&docid=" . $ID; 
     print OUT "$testurl\n"; 
     sleep 1; 

    } 

a cały skrypt

# !c:/Perl/bin/Perl.exe 


#----------------------------------------------- 
#Modules 
#----------------------------------------------- 
use XML::Simple; 
use LWP; 
use Data::Dumper; 
$Data::Dumper::Indent = 1; 
$Data::Dumper::Sortkeys = 1; 
use strict; 
use warnings; 

#----------------------------------------------- 
#Declare variables 
#----------------------------------------------- 
    my $script = "LiveContent Auto Cache Script"; # Name of the script 
    my $version = "Version 0.1"; 
    #my $pubId = "COMP-20110922XXXX"; 
    my $pubId = "LiveContentDoc";  
    my $OUT = "output.txt"; 
    my $LOG = "cacher-log.log";  # Location of log file 
    my $DATE;             # Date in form 2001-sep-01 
    my $DATENR;            # Date in form 2001-01-09 
    my $TIME;            # Time in form 12:04:03 
    my $txtmesg = ""; 
    my $resource; 
    my $xs; 
    my $doc; 

#################################### 
########### Main Program ########### 
#################################### 
error_logger();        # Open Log file and time stamp it 
request_url(); #Open the xml url and read it in 
file_write(); #write the contents of the xml url to a file 


#----------------------------------------------- 
sub request_url { 
#----------------------------------------------- 
my $useragent = LWP::UserAgent->new; 
my $request = HTTP::Request->new(GET => "http://digitalessence.net/resource.xml"); 
#my $request = HTTP::Request->new(GET => "http://dronlineservices.letterpart.com/web/content.xql?action=index&lang=en&pub=" . $pubId); 
$resource = $useragent->request($request); 
$xs   = XML::Simple->new(); 
$doc  = $xs->XMLin($resource->content); 

} 


#----------------------------------------------- 
sub file_write { 
#----------------------------------------------- 
open OUT, ">>$OUT" or Log_message ("\n$DATE - $TIME - ERROR - Could not create filelist.doc \t"); 
Log_message ("\n$DATE - $TIME - INFO - Opened the output file"); 
my $total = scalar keys %{ $doc->{ resource } }; 
Log_message ("\n$DATE - $TIME - INFO - Found: " . $total . " resources"); 
#printf "resources: %s\n", scalar keys %{ $doc->{ resource } }; 



use IO::Handle; 
STDOUT->autoflush(1); 

foreach (keys %{ $doc->{ resource } }) { 
    #print OUT $doc->{ resource }->{ $_ }->{ id }, "\n"; 
    my $ID = $doc->{ resource }->{ $_ }->{ id }, "\n"; 
    Log_message ("\n$DATE - $TIME - INFO - Found: " . $ID); 


    my $testurl = "http://dronlineservices.letterpart.com/web/content.xql?action=doc_html&lang=en&pub=" . $pubId . "&docid=" . $ID; 
    print OUT "$testurl\n"; 


     # my $browser = LWP::UserAgent->new; 
     # $browser->timeout(240); 
     # $browser->env_proxy; 
     # $browser->agent('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'); 

      # my $response = $browser->get($testurl); 

     # if ($response->is_success) { 
      #  print "\n############################\n"; 
      #  print "$testurl\n"; 
      #  print "\n############################\n"; 
       # print $response->decoded_content; # print the response out 
      # } 
      # else { 
      # my $error = $response->status_line; 
      #  Log_message ("\n$DATE - $TIME - WARN - Can't load $ID because: $error"); 
      # die $response->status_line; 

     # } 



    #my $loadrequest = $ua->get('http://dronlineservices.letterpart.com/web/content.xql?action=doc_html&lang=en&pub=" . $pubId . "&docid=" . $ID'); 
    sleep 1; 

} 


Log_message ("\n$DATE - $TIME - INFO - Written the output file"); 
#close(OUT) or Log_message ("\n$DATE - $TIME - WARN - Failed to close the Output file"); 
Log_message ("\n$DATE - $TIME - INFO - Closed the output file"); 
} 
#----------------------------------------------- 
sub error_logger { 
#----------------------------------------------- 
    time_stamp();                                # Run Time stamp sub 
    open LOG, ">>$LOG" or die ("could not open log file <$LOG>");        # Open Log File 
    Log_message ("\n$DATE - $TIME - -----------------------------------------\ \t"); 
     Log_message ("\n$DATE - $TIME - INFO - Start of Application\ \t"); 
     Log_message ("\n$DATE - $TIME - INFO - $script\ \t"); 
     Log_message ("\n$DATE - $TIME - INFO - $version\ \t"); 
     Log_message ("\n$DATE - $TIME - -----------------------------------------\ \t"); 

} 
#------------------------------------------------------------- 
sub Log_message { 
#------------------------------------------------------------- 
    time_stamp();     # Run time_stamp every time the log is written to 
    my($mesg) = @_; 
    print LOG $mesg if $LOG; # Print to log file 
    print $mesg;    # Print to Screen 
    $txtmesg = $mesg; 
    #print "\nLOGGING: $txtmesg\n"; 
} 
#----------------------------------------------- 
sub time_stamp { 
#----------------------------------------------- 
    my($Sec,$Min,$Hour,$Day,$MonthNr,$Year) = localtime(time()); 
    my $Month=("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")[$MonthNr]; 
    $Sec = sprintf("%02d",$Sec); 
    $Min = sprintf("%02d",$Min); 
    $Day = sprintf("%02d",$Day); 
    $MonthNr = sprintf("%02d",++$MonthNr); 
    $Year = 1900 + $Year; 
    $DATE = "$Year-$Month-$Day"; 
    $DATENR = "$Year-$MonthNr-$Day"; 
    $TIME = "$Hour:$Min:$Sec"; 
} # end sub 

Odpowiedz

16

zapomniałeś wybrać pierwszy uchwyt.

select((select(OUT), $| = 1)[0]); 
+4

Aby uzyskać pewne wyjaśnienia na temat tej linii kodu, warto przeczytać jest dokumentacja ('perldoc perlvar'): _ Jeśli ustawione na niezerowe, wymusza natychmiastowe kasowanie i po każdym zapisaniu lub wydrukowaniu ** na aktualnie wybranym ** kanale wyjściowym._ –

+0

Dziękuję bardzo. Teraz, aby przeczytać dokumenty, aby mieć więcej sensu! –

+9

użyj IO :: Handle; OUT-> autoflush (1); jest o wiele bardziej czytelny –

11
use IO::Handle; 
OUT->autoflush(1); 

Ale lepiej jest użyć uchwytów plików leksykalne:

use IO::Handle; 
open my $outfh, ">>", $OUT or Log_message ("\n$DATE - $TIME - ERROR - Could not create filelist.doc \t"); 
$outfh->autoflush(1); 
+1

, który jest niezawodny, bez żadnych parensów. Plus pytanie, jak poprawnie używać '$ |'. Twoja odpowiedź nie rozwiązuje tego problemu. Na koniec mówisz o leksykalnej rękojeści, ale nie masz na myśli tego. Masz na myśli własnoręcznie obsługiwane uchwyty. – tchrist

+3

@tchrist, Oczywiście, że tak. Prawidłowym sposobem użycia '$ |' jest nieużywanie go przez 'autoflush'. – ikegami

+0

@ikegami To dość głupie poczucie "poprawności". '$ |' Nie jest przestarzałe i nie ma powodu, aby udawać, że tak jest. – tchrist

Powiązane problemy