Solved

URGENT problem with compound files

Posted on 2000-03-27
6
356 Views
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;
                }
        }
        else
        {
                // 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.
        COleDocument::Serialize(ar);
}

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.
0
Comment
Question by:mintcake
  • 3
  • 2
6 Comments
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
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.
0
 
LVL 3

Expert Comment

by:Try
Comment Utility
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.
0
 

Author Comment

by:mintcake
Comment Utility
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
yourdoc::Serialize
{
ColeDocument::Serialize(ar)
if ( ar.IsStoring )
{
//do your stuff
ar.Flush();
ar.GetFile()->Flush();
if ( m_lpRootStg )
m_lpRootStg->Commit(STGC_OVERWRITE);
// 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.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 9

Accepted Solution

by:
ShaunWilde earned 200 total points
Comment Utility
Glad you found it - at least I was close with the streams - you had better delete this question before someone answers it anyway
0
 

Author Comment

by:mintcake
Comment Utility
Not the correct answer but close.
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
aww shucks - you shouldn't have :)
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
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.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

762 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now