Problem with MFC CDocument::Serialize

Started by
8 comments, last by jeroenb 18 years, 3 months ago
in my serialize function, I serialize to a file using an std::ofstream with the filename retrieved by CString FullPath = ar.GetFile()->GetFilePath();. after I directy return from the serialize function, my file is ok. then CDocument::ReleaseFile is called, steepping throuhg it should that it calls pFile->Close() where pFile is a CFile*, and this funciton makes my file blank, 0 bytes. what am I doing wrong?
Advertisement
bump
I am a little confused about the setup here. Your writing into a std::ofstream in your serialize function. Then in ReleaseFile its a CFile? What ever happens to the std::ofstream file? Do you properly close that? Maybe some code would help people see the problem.
moe.ron
pseudocode:

CString FullPath = ar.GetFile()->GetFilePath();if (ar.IsStoring()){ ofstream of(FullPath); <serialize to of> of.close(); return; //By here, the file is OK.}


The thing is, return returns to the calling function (OnSaveDocument)
Serialize(saveArchive);     // save mesaveArchive.Close();ReleaseFile(pFile, FALSE); //the evil one


Realease file then calls pFile->Close(), which blanks out my file. Any ideas?
When Serialize is called, the CFile already points to the open file. Use the attach function of ofstream to attach it to the CFile handle. You probably don't need to close it with ofstream. The destructor of CFile and ofstream should handle that for you.

Happy Coding.
Is there some way around this? as I'm using a serialization function that takes the name of the file to serialize to as a char* or wchar_t*.
bump
Why are you using the std file? CFile has at least the same functionality and works perfectly. I would use the CFile or an overloaded class.

But what probably happens is that CDocument first opens the file for writing. Then you open the file and write stuf to it. Finaly CDocument closes the file again without writting anything to it, resulting in an empty file.

Crafter 2D: the open source 2D game framework

?Github: https://github.com/crafter2d/crafter2d
Twitter: [twitter]crafter_2d[/twitter]

Correct me if I'm wrong; but, isn't CArchive derived from an iofstream? You should be able to write directly to the file using the ar parameter. Unless this has changed since VC 6.0 days.

MSDN to the rescue!!!!!

Yep, CArchive is, in fact, derived from an iofstream. Don't bother using an std::ofstream in the Serialize function. Instead, call the ar.IsStoring() to check if the Serialize function was called to store data to the file.

Here's some code to help visualize this:

void CAge::Serialize( CArchive& ar ) {   CObject::Serialize( ar );   if( ar.IsStoring() )     ar << m_years;   else     ar >> m_years; }


So, to sum it up:
There's no need to use std::ofstream, because CArchive already supports that functionality; otherwise, CArchive would pretty much be a useless class. Which it isn't. ;)

EDIT: Ok, it isn't derived from an std::iofstream. But it looked like it when I first looked at the class member functions. Hooray for literacy!
A CArchive doesnt realy have to use a file as underlying storage. It is also possible to serialize data over a socket, etc. But by default the CDocument uses a CFile object (which just uses the windows file api).

I believe it is possible to get the underlying file handle, but I have no idea how to attach that to a ofstream. As said before, just use the archive to store your data like Dorvo showed is easiest.

Crafter 2D: the open source 2D game framework

?Github: https://github.com/crafter2d/crafter2d
Twitter: [twitter]crafter_2d[/twitter]

This topic is closed to new replies.

Advertisement