Code:
' file : mmfdemo.bas ' may 8 2004 ' placed in public domain by author, michael mattias racine wi ' compiler : pb/windows 7.02 ' win32api.inc : 5/9/02 ' shows: use of memory mapped file and absolute array to replace fixed-record-length ' files using random access, using some 'wrapper' functions to make access simpler ' from within pb code. ' note this 'array' method only works with fixed-record-length files ' --------------------------------------------------------------------------- ' want more on mmfs? ' http://www.powerbasic.com/support/pb...ad.php?t=22585 (fred oxenby) ' http://www.powerbasic.com/support/pb...ad.php?t=23001 (this author) ' --------------------------------------------------------------------------- #include "win32api.inc" #if not %def (%invalid_handle_value_long) %invalid_handle_value_long = -1& #endif ' memory map a file for input only ' returns: true = pifdata, false=error function mapthisfile (szfilein as asciiz, hsys as long, hfilemapping as long, cbmapping as long) as dword ' note we need the values of hsys, hfilemapping and pifdata to unmap the file local w32 as win32_find_data, hsearch as long local pifdata as dword ' check that we can find the file, and get its size if we can hsearch = findfirstfile (szfilein, w32) if hsearch <> %invalid_handle_value_long then cbmapping = w32.nfilesizelow closehandle hsearch else function = 0 exit function end if ' open the file for reading and get system handle. we could open with pb open and then open handle but ' that would just complicate this hsys = createfile (szfilein, %generic_read, %file_share_read, byval %null, %open_existing, %file_attribute_normal, byval %null) if istrue hsys then hfilemapping = createfilemapping (hsys, byval %null, %page_readonly, byval %null, byval %null, byval %null) if istrue hfilemapping then ' map the file to our memory space and get pointer to data... pifdata = mapviewoffile (hfilemapping, %file_map_read, byval %null, byval %null, byval %null) function = pifdata else function = 0 closehandle hsys exit function end if else function = 0 exit function end if end function function unmapmappedfile (pifdata as dword, hsys as long, hfilemapping as long) as long unmapviewoffile pifdata closehandle hfilemapping closehandle hsys end function %record_length = 80 function pbmain() as long local pifdata as dword, hsys as long, hfilemapping as long, cbmapping as long, szfile as asciiz * %max_path local nrec as long, reclen as long local a() as string * %record_length ' will be our "random access file" ' for demo, build a test file. szfile = "mmftestfile.dat" nrec = 10000 reclen = %record_length call createtestfile (szfile, nrec, reclen) ' map the file and get pointer to start of data pifdata = mapthisfile (szfile, hsys, hfilemapping, cbmapping) ' overlay an array redim a (nrec -1) at pifdata ' prove success call checkafewentries (a()) ' clean up unmapmappedfile pifdata, hsys, hfilemapping msgbox "end of demo",%mb_iconinformation or %mb_applmodal, "memory-mapped file demo" end function function createtestfile (szfile as asciiz, nrec as long, reclen as long) as long local hfile as long, w as string, i as long hfile = freefile open szfile for random as hfile len=reclen for i = 1 to nrec w = lset$ (using$("this is record number ###,###", i), reclen) put #hfile, i, abs w next close hfile end function function checkafewentries (a() as string * %record_length) as long local recno as long, w as string, msg as string do w = inputbox$("record number or <cancel> to quit ", "memory-mapped file demo") if w = " then exit do else w = trim$(w) recno = val(w) - 1 ' minus one to account for zero-based array versus 1-based file if recno < lbound(a,1) or recno > ubound(a,1) then msg = "requested record out of array range" else msg = trim$(a(recno)) end if msgbox using$("trimmed record _# ###,### ==>'", recno+1) & msg & "'" ' +1 : array subscript==>record number end if loop end function ' /// end of file mmfdemo.bas
------------------
michael mattias
tal systems inc.
racine wi usa
mailto:[email protected][email protected]</a>
www.talsystems.com