Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

How do I flush/unbuffer an output filehandle? Why must I do this?

by faq_monk (Initiate)
on Oct 08, 1999 at 00:23 UTC ( [id://644]=perlfaq nodetype: print w/replies, xml ) Need Help??

Current Perl documentation can be found at perldoc.perl.org.

Here is our local, out-dated (pre-5.6) version:

The C standard I/O library (stdio) normally buffers characters sent to devices. This is done for efficiency reasons, so that there isn't a system call for each byte. Any time you use print() or write() in Perl, you go though this buffering. syswrite() circumvents stdio and buffering.

In most stdio implementations, the type of output buffering and the size of the buffer varies according to the type of 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 (e.g. modems, terminals) are normally line-buffered, and stdio sends the entire line when it gets the newline.

Perl does not support truly unbuffered output (except insofar as you can syswrite(OUT, $char, 1)). What it does instead support is ``command buffering'', in which a physical write is performed after every output command. This isn't as hard on your system as unbuffering, but does get the output where you want it when you want it.

If you expect characters to get to your device when you print them there, you'll want to autoflush its handle. Use select() and the $| variable to control autoflushing (see perlvar/$ and select):

    $old_fh = select(OUTPUT_HANDLE);
    $| = 1;
    select($old_fh);

Or using the traditional idiom:

    select((select(OUTPUT_HANDLE), $| = 1)[0]);

Or if don't mind slowly loading several thousand lines of module code just because you're afraid of the $| variable:

    use FileHandle;
    open(DEV, "+</dev/tty");      # ceci n'est pas une pipe
    DEV->autoflush(1);

or the newer IO::* modules:

    use IO::Handle;
    open(DEV, ">/dev/printer");   # but is this?
    DEV->autoflush(1);

or even this:

    use IO::Socket;               # this one is kinda a pipe?
    $sock = IO::Socket::INET->new(PeerAddr => 'www.perl.com',
                                  PeerPort => 'http(80)',
                                  Proto    => 'tcp');
    die "$!" unless $sock;

    $sock->autoflush();
    print $sock "GET / HTTP/1.0" . "\015\012" x 2;
    $document = join('', <$sock>);
    print "DOC IS: $document\n";

Note the bizarrely hardcoded carriage return and newline in their octal equivalents. This is the ONLY way (currently) to assure a proper flush on all platforms, including Macintosh. That the way things work in network programming: you really should specify the exact bit pattern on the network line terminator. In practice, "\n\n" often works, but this is not portable.

See the perlfaq9 manpage for other examples of fetching URLs over the web.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-10-12 15:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.