URGENT problem with compound files

Posted on 2000-03-27
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.
Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.


Accepted Solution

ShaunWilde earned 200 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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

778 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