Clear File Cache

Category: Files/Folders

Date: 02-16-2022

Return to Index


 
'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


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm