ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
7.12. Flushing OutputProblemWhen printing to a filehandle, output doesn't appear immediately. This is a problem in CGI scripts running on some programmer-hostile web servers where, if the web server sees warnings from Perl before it sees the (buffered) output of your script, it sends the browser an uninformative SolutionDisable buffering by setting the per-filehandle variable $old_fh = select(OUTPUT_HANDLE); $| = 1; select($old_fh); Or, if you don't mind the expense, disable it by calling the use IO::Handle; OUTPUT_HANDLE->autoflush(1); DiscussionIn most stdio implementations, buffering varies with the type of output device. Disk files are block buffered, often with a buffer size of more than 2K. Pipes and sockets are often buffered with a buffer size between 1/2 and 2K. Serial devices, including terminals, modems, mice, and joysticks, are normally line-buffered; stdio sends the entire line out only when it gets the newline. Perl's Control output buffering through the Example 7.6: seeme#!/usr/bin/perl -w # seeme - demo stdio output buffering $| = (@ARGV > 0); # command buffered if arguments given print "Now you don't see it..."; sleep 2; print "now you do\n"; If you call this program with no arguments, STDOUT is not command buffered. Your terminal (console, window, telnet session, whatever) doesn't receive output until the entire line is completed, so you see nothing for two seconds and then get the full line The dubious quest for increasingly compact code has led programmers to use the return value of select((select(OUTPUT_HANDLE), $| = 1)[0]); There's another way. The FileHandle and IO modules provide a class method called use FileHandle; STDERR->autoflush; # already unbuffered in stdio $filehandle->autoflush(0); If you're willing to accept the oddities of indirect object notation covered in Chapter 13, Classes, Objects, and Ties, you can even write something reasonably close to English: use IO::Handle; # assume REMOTE_CONN is an interactive socket handle, # but DISK_FILE is a handle to a regular file. autoflush REMOTE_CONN 1; # unbuffer for clarity autoflush DISK_FILE 0; # buffer this for speed This avoids the bizarre To ensure that your output gets where you want it, when you want it, buffer flushing is important. It's particularly important with sockets, pipes, and devices, because you may be trying to do interactive I/O with these - more so, in fact, because you can't assume line-buffering. Consider the program in Example 7.7. Example 7.7: getpcomidx#!/usr/bin/perl # getpcomidx - fetch www.perl.com's index.html document use IO::Socket; $sock = new IO::Socket::INET (PeerAddr => 'www.perl.com', PeerPort => 'http(80)'); die "Couldn't create socket: $@" unless $sock; # the library doesn't support $! setting; it uses $@ $sock->autoflush(1); # Mac *must* have \015\012\015\012 instead of \n\n here. # It's a good idea for others, too, as that's the spec, # but implementations are encouraged to accept "\cJ\cJ" too, # and as far as we've seen, they do. $sock->print("GET /index.html http/1.1\n\n"); $document = join('', $sock->getlines()); print "DOC IS: $document\n"; There's no way to control input buffering using any kind of flushing discussed so far. For that, you need to see Recipes Recipe 15.6 and Recipe 15.8. See AlsoThe |