Object-Oriented Analysis and Design of Winzip - C ++ Stream Technology (1)

zhaozj2021-02-11  227

Regenerate a Winzip

--C flow technology object-oriented object analysis and design

*********************************************************** *******************

Object-oriented analysis (OOA) and programming (OOP) technology have been mature, but now, many programmers still can't actively apply object-oriented ideas to design and develop software. In this article, I will introduce the programmer how the programmer is designed with OOA and OOP in the development and design process of file segmentation and merge tool.

One function concept and overall implementation

Before designing a software, be sure to find what kind of functionality is available. The main idea of ​​design file segmentation merge tool begins with a large file into small pieces to facilitate transmission, and it can be merged if necessary. I use this tool software to use UML as follows:

Figure 1 case example of system

It can be seen that the function of this tool software is almost exactly the same as Winzip.

The function is determined to consider the system design problem. It should be pointed out that different software systems are different, and its design phase is different. For now this gadget software, it can be considered directly to achieve its implementation technology.

In C / C , the file is regarded as a byte stream, and provides several ways to operate the file:

L C language: open and close files with fopen (), fclose (), then, then process the byte stream directly in memory;

l STL mode: use the Iostream class in the standard template library (STL);

l The class provided by the specific development environment: CFILE, CMEMFILE, etc. in VC;

The C language does not meet the OOP style, the STL is powerful, but the development effort in this example is relatively large. The development tool I use is C Builder, and the TSTREAM class is also able to meet the requirements, so it is used to develop this software from the actual number of VCL class libraries.

From the system function, it is clear that the basic operation function of the stream must be provided first, and the FileStreamopt class is designed to complete these functions for this purpose of opening, merge, extraction, etc. The interface of the FileStreamopt class is shown below:

Class FileStreamopt

{

PUBLIC:

__fastcall filestreamopt (); // Constructor

__fastcall ~ filestreamopt (); // Destructor

/ / Open the stream according to the specified file name and open mode

TFileStream * __fastcall OpenFileStream (String FileName, String OpenMode);

// Close a stream

Void __fastcall closeestream (TSTREAM * PSTREAM);

/ / Add a stream PStreamsecond to the tail of a stream PStreamFirst

BOOL __FASTCALL APPENDSTREAM (TSTREAM * PSTREAMFIRST, TSTREAM * PSTREAMSECOND);

// Extract the flow content of the Size byte starting from BeGin to store the file newfilename

BOOL __FASTCALL ExtractStream (TSTREAM * PSTREAM, STRING NewFileName, Int Begin, Int Size, Bool overcover;

// Remove the size byte starting in the stream PStream

BOOL __FASTCALL CUTOUTSTREAM (TSTREAM * PSTREAM, INT BEGIN, INT Size);

It should be pointed out that in order to achieve versatility, the interface uses the flow base type pointer parameter TSTREAM *, so that the result of these functions can be used for all subclasses of the TSTREAM class.

Data structure

Since a number of files in a file is stored, it is clear that there must be a data structure to save the information about the file, and the easiest thing to think is to define a Struct, then write this structure to the file. But more reasonable is to generate a file information class (FileInfo). The interface is as follows:

Class fileInfo: Public Tcomponent

{

Private:

String ffilename;

Int ffilesize;

Bool FneedMerge;

Int fmergeno;

Int fmergeTotaNum;

String ffilepath;

PUBLIC:

__fastcall fileinfo (tcomponent * aowner);

FileInfo & Operator = (fileInfo & a);

__publish:

//file name

__property string filename = {read = fFilename, Write = ffilename};

//file path

__property string filepath = {read = ffilepath, Write = ffilepath};

//File size

__property int filesize = {read = ffilesize, write = ffilesize};

// Do you need a merger. That is, this is a split file.

__Property Bool NeedMerge = {Read = FneedMerge, Write = FneedMerge};

// A total number of files can be divided.

__Property Int MergetotaNum = {Read = FMergetotaNum, Write = FmergeTotalNum};

// To merge file file sequence number

__Property Int Mergeno = {Read = Fmergeno, Write = fMergeno};

}

An instance of a FileInfo class (object) corresponds to a file stream object. When saving the file package, all fileInfo objects in the package are written in a package file, and the number of objects in the previous write object (the total number of files included in the package, the INT type), which is the actual data of each file. When opening a file package, first read the first int data, then a loop, read all fileInfo object data, rebuild these objects in memory.

Each file stream in the package forms a file package in order to form a file package, and each file can be calculated by the order in the file in the package and the size of all files before it.

In this way, when the software runs, the deduplication file is reflected in the insertion and deletion of the file stream for the file stream.

Now there is a problem now: How do these FileInfo objects? Do you want to define an array or a list? The most suitable method is to select the container provided by STL - List and Vector:

l Vector: Dynamic array, the disadvantage is to move the rest of the elements when adding and deleting elements in the middle, and the efficiency is not as high as LIST;

l List: Increase the deletion element very fast, but does not support random storage, if you want to access the element according to a serial number, you must start from the beginning, or with a Find () method. In my software, if you always increase the file in the end of the vector, you will not have a problem with the mobile object. Of course, you need to move the elements in the container when you delete the file, but this is not the most commonly used operation, and the file stored in a file will not be too much. The time spent on the delete file is mainly on the file flow activity instead of the vector internal element. Mobile, so I finally decided to use the Vector management of the fileInfo object, so that this file can be used in the file in the container with a file corresponding to a file.

It is worth noting that the STL requires a custom object to be overloaded to assign the operator, so I overloaded the "=" operator in the FileInfo class.

FileInfo & fileInfo :: Operator = (fileinfo & a)

{

// Overloaded assignment operator

// Note: In order to avoid errity errors when compiling,

/ / To set the return value and the parameters to reference

FFileName = a.filename;

FFilePath = a.filepath;

FFileSize = a.filesize;

FMergeno = a.mergeno;

FMergetotaNum = a.mergetotalnum;

FNEEDMERGE = a.needmerge;

RETURN * THIS;

}

The following considerations of the storage problem of Fileinfo objects: In the single document structure of the MFC, you can store objects in the stream with "<<" and ">>", but I don't use the MFC framework in BCB, of course, I can Define a class that is inherited by STL to implement this feature. In fact, the READComponent () and WriteComponent () methods have implemented in the base class of all current objects of TSTREAM, so as long as the FileInfo object is inherited Tcomponent, this object can be saved to the stream, and now you can write additional code.

It should be pointed out that the information that needs to be saved must be designed in the BCB in the PROPERTY, put it in the Published section, for data members in the public part, WriteComponent () does not save its value, this seems not very cool, but this Is it a inevitable price of something that I want to use someone else's packing, isn't it? Fortunately, this is more than yourself to write a similar method.

With a fileinfo class to represent a file information, enhance the scalability of the program, I only need to increase the data member to add new information, such as adding a file attribute and a description information for each file, It does not have to change, none of its preservation and reading code, nor does it consider the size of the size when writing files, this Borland's programmer has taken into account when designing readcomponent () and WriteComponent () methods.

Three Design Functions: FileCutmerge This class implements the basic function of the software, its interface is as follows: typedef std :: vector fileinfos;

Class Filecutmerge: Public Tcomponent

{

Private:

// Operating stream object pointer

FileStreamopt * pstreamopt; // Current File Package

TFileStream * ppackage;

// Total to point to the file information object

FileInfo * pinfo;

// Container pointer for saving file information objects

Fileinfos * pvector;

// The total number of files in the current package

Int filenum;

// Pointer starting with file content

Int filebegin;

// File package file name

String pkgfilename;

PUBLIC:

// Get the distance of the specified file stream and the file package in the file package

INT __fastcall getfileoffset (unsigned int num);

// Class constructor 1

__fastcall filecutmerge (String PackageFileName, Bool Needcreate, Tcomponent * aowner);

// Add a function to the package

BOOL __FASTCALL AddFile (String filename);

// classification function

__fastcall ~ filecutmerge ();

/ / Get the number of files in the file package

INT __fastcall getfilenum ();

/ / Get the fileInfo object of the specified file in the package

FileInfo * __fastcall getfileinfo (unsigned int num);

// Expand the specified file to disk

BOOL __FASTCALL Extractfile (unsigned int num, string path, bool overcover);

// Expand all files

BOOL __FASTCALL ExtractAllFiles (String Path, Bool overcover);

/ / Delete a file

Bool __fastcall deleteafile (unsigned int No);

// Split the file package

Bool __fastcall splitfile (String FileName, String Path, INT Size);

// Rehabilize the divided file package

Bool __fastcall mergefile; "); String MergeFileName;

// Read the file package file size

INT __fastcall getpackagesize ();

// Class constructor 2

__fastcall filecutmerge (tcomponent * oowner);

// Open a file package

Bool __fastcall openpackage (string packagefilename); Bool Needcreate;

// Create a new file package

Bool __fastcall newpackage (String packagefilename);

/ / Package file name

__property string packagefilename = {read = pkgfilename, Write = pkgfilename};

// store the package file into the disk

BOOL __FASTCALL SAVEPACKAGETODISK ();

}

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

New Post(0)