streambufs.html revision 1.1.1.2
1<?xml version="1.0" encoding="UTF-8" standalone="no"?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Stream Buffers</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.78.1" /><meta name="keywords" content="ISO C++, library" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="../index.html" title="The GNU C++ Library" /><link rel="up" href="io.html" title="Chapter��13.�� Input and Output" /><link rel="prev" href="io.html" title="Chapter��13.�� Input and Output" /><link rel="next" href="stringstreams.html" title="Memory Based Streams" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Stream Buffers</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="io.html">Prev</a>��</td><th width="60%" align="center">Chapter��13.�� 3 Input and Output 4 5</th><td width="20%" align="right">��<a accesskey="n" href="stringstreams.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.io.streambufs"></a>Stream Buffers</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="io.streambuf.derived"></a>Derived streambuf Classes</h3></div></div></div><p> 6 </p><p>Creating your own stream buffers for I/O can be remarkably easy. 7 If you are interested in doing so, we highly recommend two very 8 excellent books: 9 <a class="link" href="http://www.angelikalanger.com/iostreams.html" target="_top">Standard C++ 10 IOStreams and Locales</a> by Langer and Kreft, ISBN 0-201-18395-1, and 11 <a class="link" href="http://www.josuttis.com/libbook/" target="_top">The C++ Standard Library</a> 12 by Nicolai Josuttis, ISBN 0-201-37926-0. Both are published by 13 Addison-Wesley, who isn't paying us a cent for saying that, honest. 14 </p><p>Here is a simple example, io/outbuf1, from the Josuttis text. It 15 transforms everything sent through it to uppercase. This version 16 assumes many things about the nature of the character type being 17 used (for more information, read the books or the newsgroups): 18 </p><pre class="programlisting"> 19 #include <iostream> 20 #include <streambuf> 21 #include <locale> 22 #include <cstdio> 23 24 class outbuf : public std::streambuf 25 { 26 protected: 27 /* central output function 28 * - print characters in uppercase mode 29 */ 30 virtual int_type overflow (int_type c) { 31 if (c != EOF) { 32 // convert lowercase to uppercase 33 c = std::toupper(static_cast<char>(c),getloc()); 34 35 // and write the character to the standard output 36 if (putchar(c) == EOF) { 37 return EOF; 38 } 39 } 40 return c; 41 } 42 }; 43 44 int main() 45 { 46 // create special output buffer 47 outbuf ob; 48 // initialize output stream with that output buffer 49 std::ostream out(&ob); 50 51 out << "31 hexadecimal: " 52 << std::hex << 31 << std::endl; 53 return 0; 54 } 55 </pre><p>Try it yourself! More examples can be found in 3.1.x code, in 56 <code class="code">include/ext/*_filebuf.h</code>, and in this article by James Kanze: 57 <a class="link" href="http://kanze.james.neuf.fr/articles/fltrsbf1.html" target="_top">Filtering 58 Streambufs</a>. 59 </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="io.streambuf.buffering"></a>Buffering</h3></div></div></div><p>First, are you sure that you understand buffering? Particularly 60 the fact that C++ may not, in fact, have anything to do with it? 61 </p><p>The rules for buffering can be a little odd, but they aren't any 62 different from those of C. (Maybe that's why they can be a bit 63 odd.) Many people think that writing a newline to an output 64 stream automatically flushes the output buffer. This is true only 65 when the output stream is, in fact, a terminal and not a file 66 or some other device -- and <span class="emphasis"><em>that</em></span> may not even be true 67 since C++ says nothing about files nor terminals. All of that is 68 system-dependent. (The "newline-buffer-flushing only occurring 69 on terminals" thing is mostly true on Unix systems, though.) 70 </p><p>Some people also believe that sending <code class="code">endl</code> down an 71 output stream only writes a newline. This is incorrect; after a 72 newline is written, the buffer is also flushed. Perhaps this 73 is the effect you want when writing to a screen -- get the text 74 out as soon as possible, etc -- but the buffering is largely 75 wasted when doing this to a file: 76 </p><pre class="programlisting"> 77 output << "a line of text" << endl; 78 output << some_data_variable << endl; 79 output << "another line of text" << endl; </pre><p>The proper thing to do in this case to just write the data out 80 and let the libraries and the system worry about the buffering. 81 If you need a newline, just write a newline: 82 </p><pre class="programlisting"> 83 output << "a line of text\n" 84 << some_data_variable << '\n' 85 << "another line of text\n"; </pre><p>I have also joined the output statements into a single statement. 86 You could make the code prettier by moving the single newline to 87 the start of the quoted text on the last line, for example. 88 </p><p>If you do need to flush the buffer above, you can send an 89 <code class="code">endl</code> if you also need a newline, or just flush the buffer 90 yourself: 91 </p><pre class="programlisting"> 92 output << ...... << flush; // can use std::flush manipulator 93 output.flush(); // or call a member fn </pre><p>On the other hand, there are times when writing to a file should 94 be like writing to standard error; no buffering should be done 95 because the data needs to appear quickly (a prime example is a 96 log file for security-related information). The way to do this is 97 just to turn off the buffering <span class="emphasis"><em>before any I/O operations at 98 all</em></span> have been done (note that opening counts as an I/O operation): 99 </p><pre class="programlisting"> 100 std::ofstream os; 101 std::ifstream is; 102 int i; 103 104 os.rdbuf()->pubsetbuf(0,0); 105 is.rdbuf()->pubsetbuf(0,0); 106 107 os.open("/foo/bar/baz"); 108 is.open("/qux/quux/quuux"); 109 ... 110 os << "this data is written immediately\n"; 111 is >> i; // and this will probably cause a disk read </pre><p>Since all aspects of buffering are handled by a streambuf-derived 112 member, it is necessary to get at that member with <code class="code">rdbuf()</code>. 113 Then the public version of <code class="code">setbuf</code> can be called. The 114 arguments are the same as those for the Standard C I/O Library 115 function (a buffer area followed by its size). 116 </p><p>A great deal of this is implementation-dependent. For example, 117 <code class="code">streambuf</code> does not specify any actions for its own 118 <code class="code">setbuf()</code>-ish functions; the classes derived from 119 <code class="code">streambuf</code> each define behavior that "makes 120 sense" for that class: an argument of (0,0) turns off buffering 121 for <code class="code">filebuf</code> but does nothing at all for its siblings 122 <code class="code">stringbuf</code> and <code class="code">strstreambuf</code>, and specifying 123 anything other than (0,0) has varying effects. 124 User-defined classes derived from <code class="code">streambuf</code> can 125 do whatever they want. (For <code class="code">filebuf</code> and arguments for 126 <code class="code">(p,s)</code> other than zeros, libstdc++ does what you'd expect: 127 the first <code class="code">s</code> bytes of <code class="code">p</code> are used as a buffer, 128 which you must allocate and deallocate.) 129 </p><p>A last reminder: there are usually more buffers involved than 130 just those at the language/library level. Kernel buffers, disk 131 buffers, and the like will also have an effect. Inspecting and 132 changing those are system-dependent. 133 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="io.html">Prev</a>��</td><td width="20%" align="center"><a accesskey="u" href="io.html">Up</a></td><td width="40%" align="right">��<a accesskey="n" href="stringstreams.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter��13.�� 134 Input and Output 135 136��</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top">��Memory Based Streams</td></tr></table></div></body></html>