URGENT problem with compound files

Posted on 2000-03-27
Medium Priority
Last Modified: 2013-11-20
I have written an application which used compound file storage, and I was having some peculiar things happening with the size of the files created by the program. So after much head scratching I decided to write a program with the minimum functionality which might exhibit the same problem, and see if it was something I was doing or something with MFC. I found that this minimum functionality program exhibited the same problem. SO I am wondering if anybody can figure what I need to do to fix it.

To create the minimum functionality program , use AppWizard to create an MFC app, (MDI or SDI, it doesn't matter), ensure that you make the application a container and enable compound files.

Overide the serialize method as follows

void CMyTestDoc::Serialize(CArchive& ar)
        if (ar.IsStoring())
                // TODO: add storing code here
                for (int i = 0; i < 100; i++)
                        ar << 0xAAAAAAAA;
                // TODO: add loading code here
                for (int i = 0; i < 100; i++)
                        DWORD temp;
                        ar >> temp;

        // Calling the base class COleDocument enables serialization
        //  of the container document's COleClientItem objects.

Run the application. Hit the save button on the toolbar. Save the file as XYZ.??? - or whatever you like. Quit the application. Check the size of the file you just saved. You will find that it is about 3.5k in size. You might want to make a copy of the file by cut and paste.

Now restart the application, load up the file you just saved, and then hit the save button again. Quit the application. If you now look at the file size - (you may need to press refresh if browsing the files using Explorer, becuase it doesn't seem to automatically refresh) - you will find that the file is 4.5k in size.

Examining the data file with the doc view shows that the new data is being appended to the file. When the file is read in the new data is being read, but the old data is still there, but not accesable.

Surely the data should have overwritten the old data, but it appears tht what it actually does is append it to the end of the file. Now when the file is so small this is not a problem. But I have files of 5mb or so, doubling up to 10mb.
Question by:mintcake
  • 3
  • 2

Expert Comment

ID: 2661051
It looks as though you are saving your files in transacted mode and you need to change that to direct mode. If you look in the MFC source you will see that all the streams are created with STGM_TRANSACTED but you need STGM_DIRECT.
I suspect it is a case of roll your own classes :( unless of course somebody else has already done them.

Expert Comment

ID: 2661490
You haven't shown how the CArchive is created.  It sounds like the document is being created in an append mode.

Serializing to a compound document is a reasonably complex process, and somewhere there may be an assumption lurking that you want to append a new stream to the document, rather than replace the document.  What I'd do is start tracing MFC code to see the way in which the file is opened.  It takes special effort to open a file for append, so this is not an accident; somewhere, there is a conscious decision in MFC to do this as an append operation.  Finding where that happens will tell you what you need to do to replace the document.  For example, there may be a CDocument state variable that controls append-vs-truncate.

Author Comment

ID: 2663531
I posted this problem on CodeGuru, and got the following response.

This happens because you are using the compound file and the way
MFC opens/commits storage, and of course the storage implementation :
MFC opens storage(COleDocumnet::m_lpRootStg) in transacted mode,
and commits it with the flag STGC_ONLYIFCURRENT.
This is the most safest way : if something happeng during save operation, old
data won't be lost.
The price is an extra disk space.
This probably not a problem for many (may be most) applications : these days
several megabytes is like several bytes 10 years ago.
If you really want to sacrifice robustness in favor of disk space, try to use the STGC_OVERWRITE in IStorage::Commit call.
You may want to overwrite SaveToStorage in your docuemnt class ( this is protected virtual function of COleDocument ) : copy this function from MFC source and change STGC_ONLYIFCURRENT to STGC_OVERWRITE.
Or ( it's not clean but should work ) do it in Serialize function
if ( ar.IsStoring )
//do your stuff
if ( m_lpRootStg )
// the second commit in ColeDocuemnt::SaveToStorage shouldn't do any harm
Hope this helps

Unfortunately this was posted anonymously, so I don't know who to thank, because after testing I found that this is the correct solution.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Accepted Solution

ShaunWilde earned 400 total points
ID: 2663731
Glad you found it - at least I was close with the streams - you had better delete this question before someone answers it anyway

Author Comment

ID: 2663981
Not the correct answer but close.

Expert Comment

ID: 2664724
aww shucks - you shouldn't have :)

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
There may be issues when you are trying to access Outlook or send & receive emails or due to Outlook crash which leads to corrupt or damaged PST file. To eliminate the corruption from your PST file, you need to repair the corrupt Outlook PST file. U…
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question