Project Iterative Development Instruction - Implementation Process of File Segmentation Storage Case (3)

xiaoxiao2021-03-06  95

Project Iterative Development Instruction - Implementation Process of File Segmentation Storage Case (3)

After the iteration 2 was completed, we got a complete code of complete compressing function. This iteated completed code is available. We completed our established tasks in iteration 2. In a group discussion in the afternoon, we continue to consider the next stage iterative goal. Since there is no format of the file file, we decided not to consider the problem in the picture format, first implement the file segmentation function. The segmentation of the file is mainly to consider that the database submission performance becomes very slow when the file file file is too large, and the purpose of the segmentation is to improve the performance of the submitted.

Iteration 3:

Split the binary flow submitted to the database; then decompressed and spliced ​​operations from the database extraction to obtain the original image file data.

Before the design and encoding of the segmentation function, we re-examined the morning code - that compressed class TloadBinaryDatatoDB, I found that this class seems to be duty, it is responsible for loading the file to stream, then compress and decompress the flow, we discovered The UncompressStream function has better versatility, as long as it is a compressed flow, it can be decompressed. The compression function seems to compress the stream loaded through the file, if the flow is obtained in another form, not in the form of file loading, then we do not know how to compress the flow. It seems to violate the functional single responsibility, and the class is responsible for the loading of the stream, also responsible for the compression of the stream; so we reacting the class with better structures to increase the reuse.

The reconstructed classes only two common methods CompressStream and UncompressStream they have flowed into parameters, and the compression and decompression functions are implemented by processing the incoming stream.

Procedure TcompressStream.com (Var Stream: TmemoryStream);

VAR

ISIZE: INTEGER;

LDestStream: TMemoryStream;

LCompressionStream: TcompressionStream;

Begin

LDestStream: = TMEMORYSTREAM.CREATE;

LCompressionStream: = TcompressionStream.create (CLmax, LDestStream);

Try

ISIZE: = stream.size; // Get the original size of the image stream

Stream.SaveTroupTream (LCompRessionsTream); // Compress the original image stream,

// LDestStream saves a compressed image stream

LCompRessionsTream.free;

stream.clear;

Stream.writeBuffer (isize, sizeof (isize)); // Write the size of the original image

Stream.copyFrom (LDestStream, 0); // Write a compressed image stream

Finally

LDestStream.free

END;

END;

Unzipped function

Procedure TcompressStream.uncompressstream (Var Stream: TmemoryStream);

VAR

DecompressionStream: TDECompRessionsTream;

Buffer: pchar;

Count: integer;

Begin

Stream.Readbuffer (Count, Sizeof (count);

GetMem (buffer, count); / / / / According to the size of the original image stream to be read, the original image stream to be read is allocated.

DecompressionStream: = TDECompressionStream.create (stream);

Try

DecompressionStream.readbuffer (buffer ^, count); // Replenish the compressed image,

/ / Then store into the buffer memory block

stream.clear;

Stream.WriteBuffer (buffer ^, count); // Save the original image stream to the Stream stream

Stream.position: = 0;

Finally

FreeMem (buffer); // Release memory

END;

END;

After repetitting, TcompressStream has undoubtedly increases reuse and has a better structure. After removing the function of loading the file, TcompressStream duties have become more silent. It can compress and decompress the streams obtained in any form. Complete TLOADBINARYDATATODB Refactoring We start considering the implementation of segmentation functionality.

In assumed a stream to be split into 5 copies, then there is a sequence we consider adding a segmentation in the database to save the segmentation order between the flow of each block.

Field Name Field Type Field Length Field Description

FID NUMBER

Primary key

F_name varchar2 50 file name

F_serial

Number

File segmentation sequence number

F_binary_data long row

Binary data

Similarly, we consider encapsulating this feature in a class. We have realized a class called TSTReamIncise. When designing this class, we have a good discussion for such a better increase in this class, first we simulate how to use this class.

For i: = 0 to incisedcount - 1 DO

Begin

StreamIncise.GetIncisesTream (LSTREAM); // Get split stream

ClientDataSet2.Append;

ClientDataSet2.fieldByname ('f_id'). Value: = i; // Urban sequence number

ClientDataSet2.fieldByName ('f_name'). Value: = ffilefullname

ClientDataSet2.fieldByname ('f_serial'). Value: = i; // Take the serial number of each split

LCompressionStream.comPressStream (LSTREAM);

(ClientDataSet2.fieldByname ('f_binary_data')

as tblobfield .loadfromstream (LSTREAM);

ClientDataSet2.post;

END;

We use code to estimate the way the class is called, and we have obtained the following information through such analog code.

1) To obtain the number of divisions of the file, if we use the above analog code, we must first get the number of divisions of the stream.

2) The TSTReamIncise stream gets the to process the stream before execution, and sets the size of the split block.

Figure:

We use FinciseSize to save the split size, the FStreamSize saves the size value of the stream, and the FremainSize saves the remainder of each split. FINCISESIZE initializes in the initialization function crete.

FINCISESIZE: = 50000; // Set the size of the segmentation

LoadFromstream overlooks the original stream.

Procedure TSTREAMINCISE.LOADFROMSTREAM (Stream: tmemorystream);

Begin

FMemoryStream: = stream; // Save a stream reference

FSTREAMSIZE: = stream.size;

Fremainsize: = fstreamsize;

GetIncisedCount gains the number of loaded raw streams.

Function TSTREAMINCISE.GETITICISEDCOUNT: Integer;

Begin

Result: = FStreamsize Div Fincisesize 1;

END;

SetStreamDefault is used to set the get stream to the initial location.

Procedure TStreamIncise.setstreamdefault;

Begin

IF assigned (fMemoryStream) Then fmemorystream.position: = 0;

END;

The core function is GetIncisesTream by calling its user to get a split stream.

Procedure TStreamIncise.getIncisesTream (Incisestream: TMemoryStream);

VAR

ImaxError: Integer;

Count: integer;

Buffer: pchar;

Begin

Count: = getBufferCount;

GetMem (buffer, count);

Try

FMemoryStream.readbuffer (buffer ^, count);

InciseStream.clear;

INCISESTREAM.WRITEBUFFER (Buffer ^, Count);

INCISESTREAM.POSITION: = 0;

FremainSize: = FremainSize - count

Finally

FreeMem (buffer);

END;

END;

Here GetBufferCount each time returns the size of the split block, when the remaining stream size is not 5000, it returns the length of the remaining stream.

Function TSTREAMINCISE.GETBUFFERCOUNT: Integer;

Begin

Result: = FINCISESIZE;

IF FremainSize

Result: = FremainSize;

END;

In the end we got a division class that can be called:

Procedure TFORM1.BUTTON8CLICK (Sender: TOBJECT);

VAR

StreamIncise: TSTREAMINCISE;

I: integer;

LSTREAM: TMEMORYSTREAM;

LCompRESSIONSTREAM: TCompRessstream;

Begin

StreamIncise: = TSTREAMINCISE.CREATE

LSTREAM: = TMEMORYSTREAM.CREATE

LCompressionStream: = Tcompressstream.create;

StreamIncise.LoadFromstream (FStream);

StreamIncise.setstreamDefault;

Try

For i: = 0 to streamincise.incisedcount - 1 DO

Begin

StreamIncise.GetIncisesTream (LSTREAM); // Get split stream

ClientDataSet2.Append;

ClientDataSet2.fieldByname ('f_id'). Value: = i; // Urban sequence number

ClientDataSet2.fieldByName ('f_name'). Value: = ffilefullname

ClientDataSet2.fieldByname ('f_serial'). Value: = i; // Take each segmentation number LCompRessionsTream.comPressStream (LSTREAM);

(ClientDataSet2.fieldByname ('f_binary_data')

as tblobfield .loadfromstream (LSTREAM);

ClientDataSet2.post;

END;

Finally

StreamIncise.free;

LSTream.free;

LCompRessionsTream.free;

END;

END;

Finally, we have added the InciseSize property, allowing programmers to modify the size of the split block after the creation class.

With such a call, we can unlock the coupling of the segmentation class specific save service, thereby increasing the possibility of the segmentation class next reuse. In the process of checking the information, we also found some segmented examples, just coupling specific business coupling, reusing this code, except for paste replication, there is basically no doctor.

Thus when it is completed, we realize the split compression of the flow, file segmentation storage case to get a good solution, through small iteration, we can get the functionality that can be used at each iteration. The code is left to consider the format of the file file. In fact, more importantly, through this development, we have made newly joined group members have achieved good programming training, making it easier to understand the specific ideas and steps to achieve a function.

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

New Post(0)