An alternative to FastFile...

Share your advanced PureBasic knowledge/code with the community.
Alberto
User
User
Posts: 25
Joined: Mon May 19, 2003 4:59 pm

An alternative to FastFile...

Post by Alberto »

Code updated For 5.20+

Below is an example of useful functions to use in alternative of FastFile library made by Rings.

The FastFile library made by Rings is amazing and surely better than my poor code but consider that:
- With this code you don't depend from any libraries because it's all made with PB internal commands.
- Maybe this code works well also on Linux while FastFile works only on windows (please Linux users tell me if this is true...)
- This code is really simple and you have only to add the prefix FF_ on your Fred's commands while on FastFile you have to manage an extra Offset variable.

Code: Select all

#FILE = 1
Global FFstart.l
Global FFpos.l
Global FFposmax.l
Global FF_EOF.l

Procedure FF_Write_Init()
  FFstart = AllocateMemory(101000)    ;Alloco 1Kbyte in più per essere sicuro di non sforare e andare in crash
  FFpos = FFstart
  FFposmax = FFstart + 100000
EndProcedure

Procedure FF_Buffer_scrivi()
  WriteData(#FILE,FFstart, FFpos - FFstart)
  FFpos = FFstart
EndProcedure

Procedure FF_WriteLong(numero.l)
  If FFpos > FFposmax
    FF_Buffer_scrivi()
  EndIf
  PokeL(FFpos, numero)
  FFpos = FFpos + 4
EndProcedure

Procedure FF_WriteString(stringa.s)
  If FFpos > FFposmax
    FF_Buffer_scrivi()
  EndIf
  PokeS(FFpos, stringa)
  FFpos = FFpos + Len(Stringa) + 1
EndProcedure

Procedure FF_Buffer_leggi()
  If FF_EOF = #False
    If Eof(#File)
      FF_EOF = #True           
    Else
      coda.l = FFposmax - FFpos
      If coda > 0
        ;Debug "Coda = " + Str(coda)
        CopyMemory(FFpos,FFstart,coda)  ;Copio la coda dei dati
      Else   
        ;Debug "non copio la coda"   
      EndIf
      FFposmax = ReadData(#FILE,FFstart + coda, 100000 - coda) + FFstart + coda
      FFpos = FFstart
    EndIf
  EndIf
EndProcedure

Procedure FF_Read_Init()
  FFstart = AllocateMemory(101000)    ;Alloco 1Kbyte in più per essere sicuro di non sforare e andare in crash
  FFposmax = FFpos   ;Mi serve per evitare di copiare la "coda2 dei dati alla prima volta
  FF_EOF = #False
  FF_Buffer_leggi()
EndProcedure

Procedure.l FF_ReadLong()
  If FFpos > (FFposmax - 1000)
    FF_Buffer_leggi()
  EndIf
  risultato.l = PeekL(FFpos)
  FFpos = FFpos + 4
  ProcedureReturn risultato
EndProcedure

Procedure.s FF_ReadString()
  If FFpos > (FFposmax - 1000)
    FF_Buffer_leggi()
  EndIf
  risultato.s = PeekS(FFpos)
  FFpos = FFpos + Len(risultato) + 1
  ProcedureReturn risultato
EndProcedure

Procedure FF_Read_Close()
  FreeMemory(FFstart)
EndProcedure

Procedure FF_Write_Close()
  FF_Buffer_scrivi()
  FreeMemory(FFstart)
EndProcedure

CreateFile(#File, "C:\Test_with_FF.txt")
Start.l = ElapsedMilliseconds()
FF_Write_Init()
For index = 1 To 1000000
  FF_WriteLong(index)   
Next
FF_Write_Close()
CloseFile(#File)
Debug "milliseconds used to write C:\Test_with_FF.txt = " + Str(ElapsedMilliseconds() - Start)

OpenFile(#File, "C:\Test_with_FF.txt")
Start.l = ElapsedMilliseconds()
FF_Read_Init()
For index = 1 To 1000000
  trash.l  = FF_ReadLong()
Next
FF_Read_Close()
CloseFile(#File)
Debug "milliseconds used to read C:\Test_with_FF.txt = " + Str(ElapsedMilliseconds() - Start)

CreateFile(#File, "C:\Test_without_FF.txt")
Start.l = ElapsedMilliseconds()
For index = 1 To 1000000
  WriteLong(#FILE,index)   
Next
CloseFile(#File)
Debug "milliseconds used to write C:\Test_without_FF.txt = " + Str(ElapsedMilliseconds() - Start)

OpenFile(#File, "C:\Test_without_FF.txt")
Start.l = ElapsedMilliseconds()
For index = 1 To 1000000
  trash.l  = ReadLong(#FILE)
Next
CloseFile(#File)
Debug "milliseconds used to read C:\Test_without_FF.txt = " + Str(ElapsedMilliseconds() - Start)

Debug "I think that is better using the FF functions..."

The code is based on the idea to use a buffer of 100Kbyte in memory where you write or read and accessing the file only using the ReadData/WriteData instructions that are quicker than ReadLong/WriteLong or ReadString/WriteString.

Maybe I've reinvented the wheel but I hope that is useful to someone.

The FastFile is surely more powerful and complete (I've not FastFileCRC32 for example) but if you only need to improve the speed of Fred's command I think that these functions are for you.

Feel free to copy it and tell me suggestion or improvement.

Alberto
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

The code is based on the idea to use a buffer of 100Kbyte in memory where you write or read and accessing the file only using the ReadData/WriteData instructions that are quicker than ReadLong/WriteLong or ReadString/WriteString.
I use that method in my file comparing program, but i am not able tu win to the Microsoft "FC" DOS command comparing speed. :cry:
Alberto
User
User
Posts: 25
Joined: Mon May 19, 2003 4:59 pm

Post by Alberto »

To see the speed comparing it's sufficient to execute the code that I've posted. The last lines in my code show the different times of execution in the debug window. It's very easy.

If you want it's easy to produce a MessageRequester instead of my debug commands.

Ciao
Alberto
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Ouch! I was looking for an alturnative for Ring's FastFile, as it is confusing as hell, and ran across yours. Unfortunately, It does not read bytes nor words, so there is no way I can use it.
Bonne_den_kule
Addict
Addict
Posts: 841
Joined: Mon Jun 07, 2004 7:10 pm

Post by Bonne_den_kule »

Shannara wrote:Ouch! I was looking for an alturnative for Ring's FastFile, as it is confusing as hell, and ran across yours. Unfortunately, It does not read bytes nor words, so there is no way I can use it.
Look at his code. It's easy to change the code to write/read bytes and words
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

yeah, i did something similar in x_openfile / x_readbyte etc. but somehow mine is quite a bit slower... i think :-)

have to test it...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply