[Zz] Object serialization and file I/O in Visual C ++

Source: Internet
Author: User
Tags object serialization truncated

Persistence and serialization

Persistence is the ability of all objects to save and load their State data. Objects with this capability can record the current object state data in some way before the application ends. When the program runs again, the data is read and restored to the status at the end of the last task. Most of the MFC classes are derived directly or indirectly from the cobject class of MFC. Therefore, these MFC classes have the ability to save and load object states and are persistent. When you use the Application Wizard to generate a document/view framework, you have provided the application with the basic code for saving and loading object state data.

To realize the persistence of objects, data that records object statuses is usually stored on disks in the form of byte streams, this process of saving status data to the disk and restoring the disk to memory is called serialization. Serialization is an important concept of MFC. It is the basis for an MFC Document/view structure application to open and save documents. When a file is loaded or saved in the MFC Framework Program, in addition to opening the file for the program to read and write, it is also passed to the application a related carchive object, in this way, persistent data is serialized.

Most MFC applications do not directly use the cfile class of MFC to read and write disk files when implementing object persistence (the detailed description of the cfile class will be carried out in the next section ), instead, you can use the carchive object and call the cfile member function to perform file I/O operations. The carchive class supports continuous binary input and output of composite objects. After constructing a carchive object or connecting it to a cfile object that represents an open file, you can specify whether an file is loaded or saved. MFC allows operators "<" and ">" to serialize multiple original data types. The raw data types include byte, word, long, DWORD, float, double, Int, unsigned int, short, and char.

For serialization of non-original data types such as cstring Objects represented by the MFC class, you can solve this problem by overloading the operators <"and">, the MFC classes and structures that can be serialized in this way include cstring, ctime, ctimespan, colevariant, colecurreny, coledatetime, coledatetimespan, csize, cpoint, crect, size, point, and rect. Besides operators "<" and ">", you can call the carchive class member functions read () and write () to complete serialization. The following code demonstrates the serialization process of int variables VARA and varb through operators:

// Store VARA and varb in the archive
Carchive AR (& file, carchive: Store );
Ar <Vara <varb;
......
// Load VARA and varb from the archive
Carchive AR (& file, carchive: load)
Ar> Vara> varb;

The carchive class contains only one data member, M _ pdocument. When you open or save commands on the execution menu, the program framework sets the data member as the document to be serialized. Note: when using the carchive class, ensure that the operations on the carchive object are consistent with the file access permissions.

In the example program to be given below, the persistent objects, such as the coordinates of key points and the number of coordinates required to draw the line, will be serialized. The member variables m_ncount and m_ptposition [100] of the document class respectively record the number and coordinates of the current point. The initial value is 0. When you click the customer area, the number of points is accumulated and the coordinates of the current point are saved. Then, the invalidate () function is used to send a wm_paint Message notification window to re-paint the customer area, and draw and link the clicked points in the re-painting code:

Void csample04view: onlbuttondown (uint nflags, cpoint point)
{
// Obtain the pointer to the document class
Csample04doc * pdoc = getdocument ();
// Save the current mouse position
Pdoc-> m_ptposition [pdoc-> m_ncount] = point;
If (pdoc-> m_ncount <100)
Pdoc-> m_ncount ++;
// Refresh the screen
Invalidate ();
Cview: onlbuttondown (nflags, point );
}
......
Void csample04view: ondraw (CDC * PDC)
{
Csample04doc * pdoc = getdocument ();
Assert_valid (pdoc );
// Draw a line for the clicked point
PDC-> moveTo (pdoc-> m_ptposition [0]);
For (INT I = 1; I <pdoc-> m_ncount; I ++)
PDC-> lineto (pdoc-> m_ptposition [I]);
}

From the code above, it is not difficult to see that in order to save the drawing results, the member variables m_ncount and m_ptposition [100] of the document class must be serialized. The document class member function serialize () provides functional support for serialization of these persistent objects through the archive class. The following code saves and loads persistent objects:

If (AR. isstoring ())
{
// Store persistent objects to files
Ar <m_ncount;
For (INT I = 0; I <m_ncount; I ++)
Ar <m_ptposition [I];
}
Else
{
// Load the Persistent object from the file
Ar> m_ncount;
For (INT I = 0; I <m_ncount; I ++)
Ar> m_ptposition [I];
}

  File I/O

Although the built-in serialization function of the carchive class is a convenient way to save and load persistent data, sometimes the program needs more control over the file processing process, for this kind of file input/output (I/O) service, Windows provides a series of related API functions, which are encapsulated into the cfile class by MFC to open the file, the basic functions of file operations, such as reading, writing, deleting, renaming, and obtaining file information, are disabled to handle any type of file operations. The cfile class is the base class of the MFC File class. It supports binary input and output without buffering. It can also be used in combination with the carchive class to support buffer-based serialization of the MFC object.

The cfile class contains a public data member m_hfile, which contains file handles associated with cfile class objects. If no handle is specified, the value is cfile: hfilenull. Since the meaning of the Data Member depends on the derived class, m_hfile is generally not recommended.

You can use the cfile class to open a file in two ways: one is to first construct a cfile class object and then call the member function open () to open the file, another method is to directly use the cfile class constructor to open a file. The following statement demonstrates the process of opening the disk file "C:/testfile.txt" using the two methods:

// Construct an instance before opening the file
Cfile file;
File. Open ("C: // testfile.txt", cfile: modereadwrite );
......
// Open the file directly through the constructor
Cfile file ("C: // testfile.txt", cfile: modereadwrite );

The cfile: modereadwrite parameter indicates the mode when a file is opened. There are more than a dozen similar flags in the cfile class. The list of these flags is as follows:

File mode flag Description
Cfile: modecreate Open the file in creation mode. If the file already exists, set its length to 0.
Cfile: modenoinherit Inheritance Not Allowed
Cfile: modenotruncate When creating a file, if the file already exists, it will not be truncated.
Cfile: moderead Open a file in read-only mode
Cfile: modereadwrite Open a file in read/write mode
Cfile: modewrite Open a file by writing
Cfile: compat Allow other processes to open files simultaneously during use
Cfile: sharedenynone Allow other processes to read and write files during use
Cfile: sharedenyread Other processes are not allowed to read files during use.
Cfile: sharedenywrite Other processes are not allowed to write files during use.
Cfile: Export exclusive Cancel all access to other processes
Cfile: typebinary Set file to binary mode
Cfile: typetext Set file to text mode

These signs can be used simultaneously through the "or" operator to meet multiple requirements. For example, you need to open a file in read/write mode. If the file does not exist, create a new one. If the file already exists, the file length is not truncated to 0. To meet this condition, you can use the cfile: modecreate, cfile: modereadwrite, cfile: modenotruncate, and other file mode signs to open the file:

Cfile file ("C: // testfile.txt", cfile: modecreate | cfile: modereadwrite | cfile: modenotruncate );

You need to close an opened file when it is no longer used. That is, you can use the member function close () or the cfile class destructor to close the file. When the last method is used, if the file is not closed, the Destructor will call the close () function implicitly to close the file, this also indicates that the cfile class object created on the stack will be closed automatically when the range is exceeded. Because the object's destructor is called, The cfile object is destroyed when the file is closed, and the cfile object still exists after the file is closed. Therefore, after explicitly calling the close () function to close a file, you can continue to use the same cfile object to open other files.

File read/write is the most common file operation method. It is mainly implemented by the cfile member functions read () and write. The function prototype is as follows:

Uint read (void * lpbuf, uint ncount );
Void write (const void * lpbuf, uint ncount );

The lpbuf parameter is the pointer to the cache where data is stored. ncount is the number of bytes to be read or written. Read () returns the actual number of bytes to be read. The value is less than or equal to ncount, if the value is smaller than ncount, it indicates that the end of the file has been read, and the file reading can be ended. If you continue to read the file, 0 is returned. Therefore, you can determine whether the actual number of bytes to read is smaller than the specified number of bytes to read or whether it is 0. The following code demonstrates how to write a file at a time and read it cyclically multiple times:

// Create and write a file to open it
Cfile file;
File. Open ("C: // testfile.txt", cfile: modewrite | cfile: modecreate );
// Write a file
Memset (writebuf, 'A', sizeof (writebuf ));
File. Write (writebuf, sizeof (writebuf ));
// Close the file
File. Close ();
// Open the file in read-only mode
File. Open ("C: // testfile.txt", cfile: moderead );
While (true)
{
// Read file data
Int ret = file. Read (readbuf, 100 );
......
// Stop the loop if it reaches the end of the file
If (Ret <100)
Break;
}
// Close the file
File. Close ();

After the write () and read () functions are executed, the file pointer is automatically moved, so you do not have to call the seek () function to locate the file pointer. The complete code containing the file locating function is as follows:

// Create and write a file to open it
Cfile file;
File. Open ("C: // testfile.txt", cfile: modewrite | cfile: modecreate );
// Write a file
Memset (writebuf, 'A', sizeof (writebuf ));
File. seektobegin ();
File. Write (writebuf, sizeof (writebuf ));
// Close the file
File. Close ();
// Open the file in read-only mode
File. Open ("C: // testfile.txt", cfile: moderead );
While (true)
{
// File pointer
Static int position = 0;
// Move the file pointer
File. Seek (Position, cfile: Begin );
// Read file data
Int ret = file. Read (readbuf, 100 );
Position + = ret;
......
// Stop the loop if it reaches the end of the file
If (Ret <100)
Break;
}
// Close the file
File. Close ();

  Summary

Persistence and file I/O are an important method for program persistence and data recording. These two different processing methods are somewhat similar in functionality, but the implementation process is quite different. In addition, these two methods have their own advantages, and readers should choose them flexibly based on the actual situation in the programming process.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.