Date: 02-16-2022
Return to Index
created by gbSnippets
'Compilable Example: (Jose Includes)
#COMPILE EXE
' 8.04
#REGISTER NONE
#DIM ALL
#TOOLS OFF
#INCLUDE "WIN32API.inc" ' 1 November 2006
%NOMMIDS = 1
%NOGDI = 1
%FILE_BUFFERSIZE = 65536 ' Base size
%OneMB = 1048576 ' Avoids typing errors <smile>
$sFile = "c:\test"
FUNCTION ClearFileCache( sFile AS STRING ) AS LONG
LOCAL hSys, hPB, Chunk, lRes AS LONG
LOCAL Buffer AS DWORD PTR
LOCAL FileSize AS QUAD
LOCAL nbLoaded AS DWORD
DIM zFile AS ASCIIZ * 256
zFile = sFile
' Open file without buffering - ie bypass the filecache
hSys = CreateFile( zFile, %GENERIC_READ, 0, BYVAL 0, %OPEN_EXISTING, %FILE_FLAG_SEQUENTIAL_SCAN OR %FILE_FLAG_NO_BUFFERING, BYVAL 0 )
IF hSys < 0 THEN
lRes = GetLastError
IF lRes = %ERROR_FILE_NOT_FOUND THEN
MSGBOX "Unable to find" + " " + sFile
ELSE
MSGBOX STR$( lRes ) + " " + "Unknown error on opening file"
END IF
FUNCTION = %True
EXIT FUNCTION
END IF
hPB = FREEFILE
OPEN HANDLE hSys AS #hPB ' from a RTFMish remark by MCM
FileSize = LOF( #hPB )
CLOSE #hPB
' Chunk reading set to file size rounded up to
' next 64KB if file size less than 8MB else set to 8MB.
IF FileSize < 128 * %FILE_BUFFERSIZE THEN ' ie 8MB
Chunk = ( FileSize\65536 - 1 * ( FileSize MOD 65536 > 0 ) ) * %FILE_BUFFERSIZE ' multiples of 64KB
ELSE
Chunk = 128 * %FILE_BUFFERSIZE ' ie 8Mb
END IF
' Allocate a buffer for reading - start at Chunk size and reduce, if necessary
DO
Buffer = VirtualAlloc( BYVAL %Null, Chunk, %MEM_RESERVE OR %MEM_TOP_DOWN, %PAGE_READWRITE )
IF Buffer = 0 THEN
lRes = GetLastError
IF lRes = %ERROR_NOT_ENOUGH_MEMORY THEN
Chunk = Chunk\2
IF Chunk = %FILE_BUFFERSIZE / 2 THEN ' => 32KB buffer, we need a 64KB buffer minimum
MSGBOX "Not enough memory for file reading"
FUNCTION = %True
EXIT FUNCTION
END IF
ELSE
MSGBOX STR$( lRes ) + " " + "Unknown error allocating memory for file reading"
FUNCTION = %True
EXIT FUNCTION
END IF
ELSE
VirtualAlloc BYVAL Buffer, Chunk, %MEM_COMMIT, %PAGE_READWRITE
EXIT LOOP
END IF
LOOP
' OK, lets read the file
DO
IF ISFALSE ReadFile( hSys, BYVAL Buffer, BYVAL Chunk, nbLoaded, BYVAL 0 ) THEN
MSGBOX "Error on reading file"
FUNCTION = %True
EXIT FUNCTION
END IF
'LOOP UNTIL nbLoaded = 0
LOOP UNTIL nbLoaded < Chunk ' Saves a ReadFile
CloseHandle( hSys )
VirtualFree BYVAL Buffer, %Null, %MEM_RELEASE
END FUNCTION
FUNCTION PBMAIN( ) AS LONG
DIM strNull AS STRING
LOCAL i AS LONG, t1, t2 AS EXT
strNull = NUL$( %OneMB )
IF DIR$( $SFile ) = "" THEN
' Write a 100MB file
OPEN $sFile FOR BINARY AS #1
FOR i = 1 TO 100
PUT$ #1, strNull
NEXT
CLOSE #1
END IF
' Clear filecache after creation, if done, and before before first read
'If IsTrue ClearFileCache( $sFile ) Then Exit Function
' Read file
t1 = TIMER ' With any timing function I always start the ball rolling with a duplicate - suspect otherwise
t1 = TIMER
OPEN $sFile FOR BINARY AS #1
FOR i = 1 TO 100
GET$ #1, %OneMB, strNull
NEXT
CLOSE #1
t1 = TIMER - t1
' Clear filecache after first reading and before second read
'If IsTrue ClearFileCache( $sFile ) Then Exit Function
' Read file again
t2 = TIMER
OPEN $sFile FOR BINARY AS #1
FOR i = 1 TO 100
GET$ #1, %OneMB, strNull
NEXT
CLOSE #1
t2 = TIMER - t2
MSGBOX USING$( "##.##", t1 ) + " " + USING$( "##.##", t2 )
END FUNCTION
'gbs_01265
'Date: 05-11-2013
http://www.garybeene.com/sw/gbsnippets.htm