Here is a comparison with the opening post and buffering on
Windows.
The first thing to do is to create a large file.
Code: Select all
Dim As Long i, f
Dim as String*262144 sData
f = Freefile
Open "500MB.dat" for Binary as #f
For i = 1 to 2000
Put #f, , sData
Next
Close #1
Print "Done"
sleep
We now have a 500MB file.
The following uses buffering and then the filecache is cleared of "500MB.dat" otherwise when we come to read "500MB.dat" again it will 'fly in'. You will have to take my word for it that ClearFileCache3 does what it says. ClearFileCache was written by me about 7 seven years ago, swiftly followed by ClearFileCache2 - a more robust version. Many folk at PowerBASIC used it when developing code as it saved them restarting their machine to clear the filecache. Comparing hash functions, for example, requires 'flushing' the filecache between functions. A couple of years ago a guy, Paul Purvis, played around with my code and found that the file did not have to be read, it only needed to be opened and then closed again. The operative flag is, of course, FILE_FLAG_NO_BUFFERING. I am not even sure that Microsoft are aware of this trick.
OK, testing time.
Buffering with a HDD, on my Win10 machine, comes in at 0.105s. The opening post method comes in at 4.063s. That is pushing 40 times faster.
If we comment ClearFileCache3( "500MB.dat" ) the opening post comes in at 0.197s. It is still slower than buffering and it is not getting data from the hard drive.
Needless to say, it we are only reading small files then the opening post is fine. With a 512KB file we get 0.000365s and 0.001938s giving buffering a 5 times edge. With the opening post coming in at 2ms do we still need to be clever? Probably not. <smille>
Code: Select all
#include once "windows.bi"
Dim buffer1 As String * 262144
Dim As Long f
Dim As Double t
Declare Function ClearFileCache3( As String ) As Long
f = Freefile
t = Timer
' Buffering method
Open "500mb.dat" For Binary As #f
Do
Get #f, ,buffer1
'Do some stuff
Loop Until Eof(f)
Close #f
t = Timer - t
Print t
ClearFileCache3( "500MB.dat" )
f = Freefile
t = Timer
' Opening post method
Open "500MB.dat" For Binary As #f
Dim As Ubyte buffer2(Lof(f))
Get #f, ,buffer2()
' Do some stuff
Close #f
t = Timer - t
Print t
Sleep
Function ClearFileCache3( sFile As String ) As Long
Dim As Long lRes
Dim As HANDLE hSys
Dim As Zstring*256 zFile
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, 0 )
If hSys < 0 Then
lRes = GetLastError
If lRes = ERROR_FILE_NOT_FOUND Then
Print "Unable to find" + " " + sFile
Else
Print Str$( lRes ) + " " + "Unknown error on opening file"
End If
Function = True
Exit Function
End If
CloseHandle( hSys )
End Function