Intermediate input/output buffer/s for filebuf objetcs

Hi,

The documentation of the class filebuf in the reference of cplusplus.com says:


Objects of this class may internally maintain an intermediate input buffer and/or an intermediate output buffer, where individual characters are read or written by i/o operations. These buffers are synchronized with the contents of the file once filled up, when explicitly requested to do so (sync), or when the object is closed.

Objects of this class may be explicitly made unbuffered by calling member pubsetbuf with both arguments set to zero (see member setbuf): Unbuffered file stream buffers perform the i/o operations directly on the file, without an intermediate buffer.


The C++ standard ensures that filebuf objects have an intermediate input/output buffer/s (i.e, the default constructor of the class filebuf creates the intermediate buffer/s)?
The standard C++ library only allows unbuffering filebuf objects (as the above quote says) but doesn't allow forcing filebuf objects to be buffered.

I have been seeying the concrete implementation code of the standard C++ library in my Windows Operating System (Windows 7 Ultimate 64 bits Service Pack 1) and it seems that fielbuf objects never uses intermediate input/output buffer/s, they use FILE streams of the standard C library instead to do the work. Are this FILE streams always buffered? If true, are they fully-buffered or line-buffered? what is the size of the buffers (perhaps macro BUFSIZ from <cstdio>)? and can I change this size?

I am worried about performance in reading and writing from/to files: if the default behaviour offers the best performance (perhaps if files are too large is better force buffering and choose a larger buffer size).

Thanks.
it seems that fielbuf objects never uses intermediate input/output buffer/s, they use FILE streams of the standard C library instead to do the work


That sounds dubious. Can you show the source code of the constructor of their filebuf?

For example,

clang's libc++ filebuf constructor sets the buffer to 4096 bytes, see http://llvm.org/svn/llvm-project/libcxx/trunk/include/fstream

gcc's libstdc++ filebuf constructor sets the buffer size to the value of BUFSIZ (which is defined in stdio.h, to 8192 on my system), and filebuf's member function open() calls the member function that allocates that buffer, see http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/include/bits/fstream.tcc?view=markup

The C++ standard ensures that filebuf objects have an intermediate input/output buffer/s

It doesn't require it, but an implementation where filebuf is unbuffered by default would be so bad, people would file QoI bug reports.
Last edited on
This is the relevant code executed in my platform:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

// First, the basic_filebuf constructor is called (with _File = 0, so no file associated)
	basic_filebuf(_Filet *_File = 0)
		: _Mysb()
		{	// construct from pointer to C stream
		_Init(_File, _Newfl);
		}

// Second, the base classs constructor (basic_streambuf) is called
	__CLR_OR_THIS_CALL basic_streambuf()
		: _Plocale(_NEW_CRT locale)
		{	// construct with no buffers
		_Init();
		}

// Third,  the _Init() method is called (which not set any buffers)
	void __CLR_OR_THIS_CALL _Init()
		{	// initialize buffer parameters for no buffers
		_IGfirst = &_Gfirst;
		_IPfirst = &_Pfirst;
		_IGnext = &_Gnext;
		_IPnext = &_Pnext;
		_IGcount = &_Gcount;
		_IPcount = &_Pcount;
		setp(0, 0);
		setg(0, 0, 0);
		}

// Fourth, the second _Init() method is called (with _File = 0 again)
	void _Init(_Filet *_File, _Initfl _Which)
		{	// initialize to C stream _File after {new, open, close}
		__PURE_APPDOMAIN_GLOBAL static _Myst _Stinit;	// initial state

		_Closef = _Which == _Openfl;
		_Wrotesome = false;

		_Mysb::_Init();	// initialize stream buffer base object

 #ifndef _IORCNT
  #define _IORCNT	_IOCNT	/* read and write counts are the same */
  #define _IOWCNT _IOCNT
 #endif /* _IORCNT */

  #pragma warning(push)
  #pragma warning(disable: 6240)	/* prefast noise VSW 489858 */
		if (_File != 0 && sizeof (_Elem) == 1)
  #pragma warning(pop)

			{	// point inside C stream with [first, first + count) buffer
			_Elem **_Pb = (_Elem **)&_File->_IOBASE;
			_Elem **_Pn = (_Elem **)&_File->_IOPTR;
			int *_Nr = (int *)&_File->_IORCNT;
			int *_Nw = (int *)&_File->_IOWCNT;
			_Mysb::_Init(_Pb, _Pn, _Nr, _Pb, _Pn, _Nw);
			}

		_Myfile = _File;
		_State = _Stinit;
		_Pcvt = 0;	// pointer to codecvt facet
		}


So no buffers are created.
Topic archived. No new replies allowed.