Memory-Mapped large files

Source: Internet
Author: User

For some small files, with ordinary file stream can be a good solution, but for large files, such as 2G or more, the file stream is not, so to use the API's memory mapping method, even the memory map, can not map the size of all files at once, so you must take a block map, Handle a small portion at a time.

Let's look at a few functions

CreateFile: Open File

GetFileSize: Get File size

CreateFileMapping: Creating Mappings

MapViewOfFile: Mapping File

See MapViewOfFile's help, his last two parameters all need to be the page granularity of the integer times, the general machine page granularity of 64k (65536 bytes), and we actually operate, is generally not such rules, arbitrary position, arbitrary length is possible, so we have to do some processing.

The task of this example is from a length list (finfolist), read the length value sequentially, and then go to another large file (Fsourcefilename) to read the specified length of the data, if it is a small file, this is good, once read the file stream, and then read it sequentially, Large numbers for large files, you need to constantly change the location of the map to get the data we want.

This example shows that the page granularity is obtained by GetSystemInfo, and then 10 times times the page granularity as a mapped block, in the for loop, the length of the read (Totallen) plus the length to be read, whether within this mapping range (10 times times the page granularity), If you continue to read, if it is exceeded, write down the rest of the data, then remap the next piece of memory, and then merge the remaining data from the record into the newly read data, a little bit around (maybe my idea is too wrapped up), the code listed below.

Procedure Tgetdatathread.dogetdata;

Var

Ffile_handle:thandle;

Ffile_map:thandle;

List:tstringlist;

P:pchar;

I,interval:integer;

Begin

Try

Totallen: = 0;

Offset: = 0;

Tstream: = tmemorystream.create;

Stream: = Tmemorystream.create;

List: = Tstringlist.create;

Get System Information

GetSystemInfo (SysInfo);

Size of page allocation granularity

BlockSize: = sysinfo.dwallocationgranularity;

Open File

Ffile_handle: = CreateFile (PChar (fsourcefilename), Generic_read,file_share_read,nil,open_existing,file_attribute_ normal,0);

If Ffile_handle = Invalid_handle_value then Exit;

Get File size

FileSize: = GetFileSize (Ffile_handle,nil);

Creating mappings

Ffile_map: = CreateFileMapping (Ffile_handle,nil,page_readonly,0,0,nil);

If Ffile_map = 0 then Exit;

Here we have 10 times times blocksize for a data block to map, if the file size is less than 10 times times blocksize, then directly map the entire file length

If FileSize div blocksize > Ten Then

Readlen: = 10*blocksize

Else

Readlen: = FileSize;

For I: = 0 to Finfolist.count-1 do

Begin

List. Delimiter: = ': ';

List. Delimitedtext: = Finfolist.strings[i];

To get the length, I did the parsing here because I stored the information for A:B:C this type, so separated by: number

Len: = Strtoint (list. STRINGS[1]);

Interval: = Strtoint (list. STRINGS[2]);

if (i = 0) or (Totallen+len >=readlen) Then

Begin

If the length of the read plus the length that is about to be read is greater than 10 times times blocksize, then we want to keep the contents of the previous mapping to merge with the newly mapped content

If i > 0 Then

Begin

Offset: = offset + Readlen;

Write temporary stream

Tstream. Write (P^,readlen-totallen);

Tstream. Position: = 0;

End

If the length of data that has not been read is not enough for one allocation granularity, then the remaining length is mapped directly

If Filesize-offset < blocksize Then

Readlen: = Filesize-offset;

Map, p is a pointer to the map area

Note that the third parameter here is always set to 0, which is set according to the actual situation

P: = PChar (MapViewOfFile (Ffile_map,file_map_read,0,offset,readlen));

End

If there is data in the staging stream, you need to merge

If Tstream. Size > 0 Then

Begin

Copy the temporary stream data.

Stream. CopyFrom (Tstream,tstream. Size);

Then write the new data at the end, merge complete

Stream. Write (P^,len-tstream. Size);

Totallen: = Len-tstream. Size;

Moves the position of the pointer, pointing to the beginning of the next data

INC (P,len-tstream. Size);

Tstream. Clear;

End

Else

Begin

Stream. Write (P^,len);

Totallen: = Totallen + len;

INC (P,len);

End

Stream. Position: = 0;

Save a stream as a file

Stream. SaveToFile (IntToStr (i) + '. txt ');

Stream. Clear;

End

Finally

Stream. Free;

Tstream. Free;

CloseHandle (Ffile_handle);

CloseHandle (FFILE_MAP);

End

End

Http://www.cnblogs.com/hnxxcxg/archive/2012/11/04/2753265.html

Memory-Mapped large files

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.