What does ifstream::rdbuf() actually do?
Asked Answered
C

3

29

I have the following code and it works pretty good (other than the fact that it's pretty slow, but I don't care much about that). It doesn't seem intuitive that this would write the entire contents of the infile to the outfile.

// Returns 1 if failed and 0 if successful
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
    ifstream infile(inFilename.c_str(), ios::binary);
    ofstream outfile(outFilename.c_str(), ios::binary);

    if( infile.is_open() && outfile.is_open() && infile.good() && outfile.good() )
    {
        outfile << infile.rdbuf();

        outfile.close();
        infile.close();
    }
    else
        return 1;

    return 0;
}

Any insight?

Closestool answered 26/1, 2010 at 18:48 Comment(1)
I would add that explicit calls to close() are not needed. Destructors would do the same anyway. And that saves some lines. ;)Framboise
S
22

Yes, it's specified in the standard and it's actually quite simple. rdbuf() just returns a pointer to the underlying basic_streambuf object for the given [io]stream object.

basic_ostream<...> has an overload for operator<< for a pointer to basic_streambuf<...> which writes out the contents of the basic_streambuf<...>.

Sharl answered 26/1, 2010 at 18:51 Comment(10)
But wouldn't operator<< just write out one chunk? It's not easy to see that it will write out the whole thing as one chunk. I understand it's a pointer to it but does that pointer contain the entire data as one chunk? I'm still a little confused.Closestool
I'm not quite sure what you are driving at with 'one chunk'? It's specified to output the contents of the pointed to streambuf character by character until the end of the buffer is reached or there is an error outputting it. The streambuf is a class instance and whether it stores its controlled sequence in contiguous memory or not is not specified and can't be inferred from the interface.Sharl
Ok, it does it character by character until the end of the buffer is reached. How do you know that? I didn't see that from the interface provided.Closestool
@Brian: It's specified in the standard.Strangle
Where is this standard documentation you are speaking of. I have looked at: msdn.microsoft.com/en-us/library/whhe46xz%28VS.80%29.aspx and cplusplus.com/reference/iostream/ios/rdbufClosestool
#82156Sharl
So there's like 10,000 standards with weird names that only people at ISO can possibly understand what they mean. Not only do you not know what you're getting, but it costs $300 for a real standard from ISO. This is ridiculous. I just want to know one simple little thing and I have to buy a stupid standard. This information should be free and readily available so people can make better code. LAME!!Closestool
@Brian T Hannan : The documentation of ostream::operator<< is available, among many other places, on MSDN: msdn.microsoft.com/en-us/library/ba4ae8wb(VS.80).aspx. No need to buy the standard for that.Leicester
@Brian T Hannan: If you read the answers to the linked question you'll find links to freely available drafts of all the relevant standards. These will be very close to the actual standards and are going to be the most reliable free reference for definitive answers.Sharl
@Eric Malenfant : Thanks! I was looking in the wrong place. I was looking in the ifstream documentation, but really where the work is being done is in "ostream::operator<<" This is much clearer now.Closestool
D
30

iostream classes are just wrappers around I/O buffers. The iostream itself doesn't do a whole lot… mainly, it provides operator>> formatting operators. The buffer is provided by an object derived from basic_streambuf, which you can get and set using rdbuf().

basic_streambuf is an abstract base with a number of virtual functions which are overridden to provide a uniform interface for reading/writing files, strings, etc. The function basic_ostream<…>::operator<<( basic_streambuf<…> ) is defined to keep reading through the buffer until the underlying data source is exhausted.

iostream is a terrible mess, though.

Disadvantage answered 26/1, 2010 at 23:27 Comment(0)
S
22

Yes, it's specified in the standard and it's actually quite simple. rdbuf() just returns a pointer to the underlying basic_streambuf object for the given [io]stream object.

basic_ostream<...> has an overload for operator<< for a pointer to basic_streambuf<...> which writes out the contents of the basic_streambuf<...>.

Sharl answered 26/1, 2010 at 18:51 Comment(10)
But wouldn't operator<< just write out one chunk? It's not easy to see that it will write out the whole thing as one chunk. I understand it's a pointer to it but does that pointer contain the entire data as one chunk? I'm still a little confused.Closestool
I'm not quite sure what you are driving at with 'one chunk'? It's specified to output the contents of the pointed to streambuf character by character until the end of the buffer is reached or there is an error outputting it. The streambuf is a class instance and whether it stores its controlled sequence in contiguous memory or not is not specified and can't be inferred from the interface.Sharl
Ok, it does it character by character until the end of the buffer is reached. How do you know that? I didn't see that from the interface provided.Closestool
@Brian: It's specified in the standard.Strangle
Where is this standard documentation you are speaking of. I have looked at: msdn.microsoft.com/en-us/library/whhe46xz%28VS.80%29.aspx and cplusplus.com/reference/iostream/ios/rdbufClosestool
#82156Sharl
So there's like 10,000 standards with weird names that only people at ISO can possibly understand what they mean. Not only do you not know what you're getting, but it costs $300 for a real standard from ISO. This is ridiculous. I just want to know one simple little thing and I have to buy a stupid standard. This information should be free and readily available so people can make better code. LAME!!Closestool
@Brian T Hannan : The documentation of ostream::operator<< is available, among many other places, on MSDN: msdn.microsoft.com/en-us/library/ba4ae8wb(VS.80).aspx. No need to buy the standard for that.Leicester
@Brian T Hannan: If you read the answers to the linked question you'll find links to freely available drafts of all the relevant standards. These will be very close to the actual standards and are going to be the most reliable free reference for definitive answers.Sharl
@Eric Malenfant : Thanks! I was looking in the wrong place. I was looking in the ifstream documentation, but really where the work is being done is in "ostream::operator<<" This is much clearer now.Closestool
A
1

A quick look at the source code shows that basic_ofstream is the wrapper around basic_filebuf.

Amphitheater answered 9/6, 2020 at 7:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.