Serialization and File IO Studies in Visual C ++

xiaoxiao2021-03-06  102

Serialization and File I / O Studies in Visual C

Persistence and serialization

Persistence is the ability to save and load their status data. Objects with this ability can record the current object status data in some way before the application ends. When the program is run again, the status of the last task is restored by reading the data again. Since most of the MFC classes are derived directly or indirectly, these MFC classes have the ability to save and load object status, which is persistent. When using an application wizard to generate a document / view structure, the basic code for the object status data saving and loading has been provided for the application.

To achieve the persistence of objects, the data of the recorded object state is usually stored in the form of a word stream to the disk, which saves status data to disk and recovery from disk to memory, referred to as serialization. Serialization is an important concept of MFC, which is the basis for the MFC document / view structure application to open, save, etc. When a file is loaded or saved in the MFC framework, in addition to opening the file, it is also passed to a related CARCHIVE object, and the serialization of persistence data is implemented.

Most MFC applications are not directly read and write with the MFC's CFILE class when implementing the Persistence of the object (detailed introduction to the CFILE class will be performed in the next section), but by using the CARCHIVE object and it is CFILE The member function is called to execute a file I / O operation. The CARCHIVE class supports the input and output of the consecutive binary form of the composite object. After constructing a CARCHIVE object or connecting it to a CFILE object indicating the open file, you can specify a file that is loaded or saved. The MFC allows sequencing a variety of raw data types using operators << and ">>". These raw data types include Byte, Word, Long, DWORD, FLOAT, DOUBLE, INT, UNSIGNED INT, SHORT, and CHAR.

For other non-raw data types, non-raw data types, such as CString objects, such as CString objects, and the like, can be solved by overloading "<<" and ">>" operators, can be serialized MFC classes in this way And the structure has CString, CTIME, CTimeSpan, Colevariant, Colecurreny, Coledatetime, ColedateTimeSpan, CSIZE, CPOINT, CRECT, SIZE, POINT, and RECT. In addition to operators "<<" and ">>" can also call the CARCHIVE class member function read () and write () to complete serialization. The following code shows the serialization process of the INT type VARA, VARB through operator:

// Store VARA, VARB to the file CARCHIVE AR (& File, Carchive :: Store); ar << VARA << varb; ... // Load VARA, VARBCARCHIVE AR (& File, Carchive :: Load) Ar> from the file > VARA >> VARB;

The CARCHIVE class only contains a data member m__pdocument. When the command is turned on or saved on the execution menu, the program framework sets the data to the document to be serialized. It is also important to note that when using the Carchive class, to ensure the unity of the operation of the CARCHIVE object and file access.

In this article, in the sample program to be given, a persistent object such as the key point coordinates and coordinates required for the drawing connection will be serialized. The members variables M_NCount and M_PtPosition [100] of the Chinese file class record the number and coordinates of the current point, respectively, and the initial value is 0. When the mouse click on the client area, the number of points is accumulated and saves the coordinate position of the current point. The client area is then redrawed by the Invalidate () function, and the client is redrawged to draw the clicks in the redraw code: void csample04view :: ONLBUTTONDOWN (UINT NFLAGS, CPOINT) {// Get Pointer csample04doc * pdoc = getDocument (); // Save the current mouse click PDOC-> m_ptposition [PDOC-> m_ncount] = Point; if (pdoc-> m_ncount <100) PDOC-> m_ncount ; // Refresh Screen INVALIDATE (); CView :: ONLBUTTONDOWN (NFLAGS, POINT);} ... Void csample04view :: onDraw (cdc * pdc) {csample04doc * pdoc = getDocument (); assert_valid (pdoc); // Connect the click point Line drawing PDC-> MoveTo (pdoc-> m_ptposition [0]); for (int i = 1; i m_ncount; i ) PDC-> Lineto (pdoc-> m_ptposition [i]);}

It is not difficult to see from the above program code, in order to save the drawing result, the member variable M_NCount and M_PTPosition [100] of the document class must be sequenced. The document member function serialize () provides functional support with serialization of these persistent objects through the Archive class. The following code completes the saving and loading of persistent objects:

IF (ar.isstoring ()) {// stores persistent objects to file ar << m_ncount; for (int i = 0; i > m_ncount; for (int i = 0; i > m_ptPosition [i];

Custom lasting class

To make a class object a lasting, you can customize a persistent class to complete the work of the storage and load of persistence data. This processing method is also more compliant with object-oriented programming requirements. You can create a custom lasting class that can serialize its member variables by the following basic procedures:

1. A new class is given directly or indirectly from the COBJECT class.

2. The declaration section of the class contains the Declare_Serial macro of the MFC, which only needs to use the class name as a parameter.

3. The serialize () function of the base class is overloaded, and the code for serializing the data is added.

4. If the constructor does not have an empty default constructor (excluding any parameters), add one.

5. In the implementation section of the class, add the MFC's Implement_Serial Macro. This macro requires three parameters: class name, base class name, and a solution number. The solution number is an integer equivalent to the version number. Whenever you change the serialized data format of the class, you should change this value in time. According to the above steps, it is not difficult to encapsulate the serialization code in the previous section. The packaged lasting class CPosition is responsible for serialization of class member variables m_ncount and m_ptposition [100], the packaged code is as follows: // CPSITION class declaration section : class cPosition: public CObject {DECLARE_SERIAL (cPosition) cPosition (); int m_nCount; CPoint m_ptPosition [100]; void Serialize (CArchive & ar); CPoint GetValue (int index); void SetValue (int index, CPoint point); virtual ~ CPSITION ();}; ... // CPSITION class implementation section: import_serial (cposition, cposit, 0) CPSITION :: CPSITION () {// Initialize M_NCount = 0 for class members; for (int i = 0; i < 100; i ) m_ptposition [i] = cpoint (0, 0);} CPSITION :: ~ cposition () {} void cposition :: setValue (int index, cpoint point) {// Set the Coordinate value m_ptposition of the specified point [INDEX ] = POINT;} CPOINT CPSITION :: getValue (int index) {// gets the coordinate value of the specified point Return m_ptposition [index];} void cposition :: serialize (carchive & ar) {cobject :: serialize (ar); if ( ar.isstoring ()) {// Store persistent objects to file ar << m_ncount; for (int i = 0; i > m_ncount; for (int i = 0; i > m_ptPosition [i];}}

After creating a custom lasting class CPosition, you can manage the coordinates of the point click by this class. Since the serialization work has been completed by the class itself, just in the serialize () function of the document class. The serialize () member function is called:

Void csample04doc :: serialize (carchive & ar) {// Using custom lasting class m_position.serialize (ar); if (ar.isstoring ()) {} else {}}

File I / O

Although serialization functions built by Carchive class is to save and load persistent data, it is sometimes necessary to have more control over the program, and the file input and output (I / O) service is required. Demand, Windows provides a series of related API functions, and packaged by MFC into CFILE class, providing basic functions of file operations such as files, closing, reading, writing, deleting, renovating, and acquiring file information. It is sufficient to handle any type of file operation. The CFILE class is the base class of the MFC file class, supports unbuffed binary input and output, or by supporting the MFC object with buffer serialization by blending with the CARCHIVE class. The CFILE class contains a public type of data member M_HFILE that contains the file handle associated with the CFILE class object. If no handle is specified, the value is cfile :: Hfilenull. Since the significance of the data is depends on the derived class, M_HFILE is generally not recommended.

Open the file through the CFILE class, you can take two ways: one way is to construct a CFILE class object and then call the member function Open () open file, and another way directly using the CFILE class constructor to open a file. The following statement demonstrates the process of opening disk file "c: /testfile.txt, respectively:

// Technically construct, then open the file cfile file; file.open ("c: //testfile.txt", cfile :: modeReadwrite; ... // Directly open file cfile file directly by constructor ("C: //Testfile.txt ", cfile :: modeReadwrite);

The parameter cfile :: ModeReadWrite is the mode flag of opening the file. There are more than a dozen flags in the CFILE class. The current list is as follows:

File mode flag Description CFile :: MODECREATE Create mode Open file, if the file already sets to 0 cfile :: modeNoinherit does not allow inheritance CFile :: MODENOTRUNCATE When you create a file, if there is a file, there is no truncation CFILE :: ModeRead Read-only mode Open file CFile :: ModeReadWrite Read and write mode Open file CFile :: ModeWrite Write open file cfile :: ShareCompat during use Allow other processes simultaneously open files CFILE :: Sharednynone during use Allow other process pairs Read and write CFILE :: SharednyRead Do not allow other processes during use CFILE :: SharednyWrite during use Do not allow other processes to write CFile :: ShareXClusive CFILE :: ShareExClusive CFILE: : Typebinary Settings Files for Binary Mode CFILE :: Typetext Settings Files for Text Mode

These markers can be used simultaneously through the "or" operator, and in this way to meet a variety of needs. For example, you need to open a file in a read-write mode. If you don't exist, create a new, if the file already exists, does not truncate its file length is 0. To meet this condition, you can use CFile :: MODECREATE, CFILE :: ModReadwrite, and CFile :: MODENOTRUNCATE to open the file:

Cfile File ("C: //TestFile.txt", CFile :: MODECREATE | CFILE :: ModeReadwrite | CFILE :: MODENOTRUNCATE

When the open file is no longer used, it needs to be turned off, that is, you can use the member function close () to shut down or the destructor of the CFILE class. When taken, if the file is not closed, the destructor will be responsible for implicitly calling a close () function to close the file, which also indicates that the CFILE class object created on the heap will be automatically closed after an exceeding range. . Due to the call of the object's destructive function, the CFILE object is also destroyed while the file is turned off, and the CFile object still exists after the CLOSE () mode is turned off. So, after explicitly call the close () function to turn off a file, you can continue to open other files with the same CFILE object. Document reading and writing is the most common file operation mode, mainly due to the CFILE class member function read (), Write (). Its function prototype is:

Uint Read (Void * lpbuf, uint ncount); Void Write (Const void * lpbuf, uint ncount);

The parameter lpbuf is a pointer to the cache of the storage data. Ncount is the number of bytes to be read or written, and READ () returns to the number of bytes actually read, the value is less than or equal to NCount, if less than ncount Already read the end of the file, you can end the file read, if you continue to read, will return 0. Therefore, it is usually possible if the actual read byte is less than whether the number of bytes of the read or whether it is 0 as a judgment file to reach the end. The following code demonstrates the processing process that reads multiple reads and loops for files:

// Create, write mode open file cfile file; file.open ("c: //testfile.txt", cfile :: modeter | cfile :: modecreate); // Writebuf, 'A', Sizeof (WriteBuf); file.write (WriteBuf, Sizeof (WriteBuf)); // Close file file.close (); // read-only mode Open file file.Open ("c: //testfile.txt", cfile :: ModeRead; while (true) {// read file data int RET = file.read (ReadBUF, 100); ... // If the end of the file is reached, the cyclic IF (RET <100) Break;} // Close file file.close ();

The write () and read () functions are executed, the file pointer will be automatically moved, so no one will be displayed to call the Seek () function to position the file pointer. The full code containing the file positioning function is as follows:

// Create, write mode open file cfile file; file.open ("c: //testfile.txt", cfile :: modeter | cfile :: modecreate); // Writebuf, 'A', SizeOf (WriteBuf); file.seektobegin (); file.write (WriteBuf, sizeof (writebuf)); // Close file file.close (); // read-only mode Open file file.Open ("C: ////// Testfile.txt ", cfile :: modeRead; while (true) {// file pointer static int position = 0; // Mobile file pointer file.seek (position, cfile :: begin); // read file data int Ret = file.read (readbuf, 100); position = ret; ... // If the end of the file ends, the loop IF (RET <100) Break;} // Close file file.close (); small knot

Persistence and document I / O are an important way to maintain and record data. Although both different processing methods are functionally close but the implementation process is large. Moreover, these two processing methods have advantages, and readers should be flexibly selected according to the actual situation during programming.

转载请注明原文地址:https://www.9cbs.com/read-105355.html

New Post(0)