Files

Share your advanced PureBasic knowledge/code with the community.
akee
Enthusiast
Enthusiast
Posts: 498
Joined: Wed Aug 18, 2004 9:52 am
Location: Penang, Malaysia

Files

Post by akee »

Code updated for 5.20+

I missed the low level file functions from CLIPPER. So here's a compatible file library to manage files and examples.

Files.pbi

Code: Select all

;info:Low-Level File Functions by AKEE... :)
#FILE_NEWLINE = Chr(13) + Chr(10)
#FILE_BUFFERSIZE = 128

#FILE_MODE_READ = 1
#FILE_MODE_WRITE = 2
#FILE_MODE_APPEND = 4

#FILE_SEEKPOS_BEGIN = 0
#FILE_SEEKPOS_CURRENT = 1
#FILE_SEEKPOS_END = 2

;
; Creates a new file.
;
Procedure fcreate(filename.s, filemode)
  ProcedureReturn CreateFile_(filename, filemode, 0, 0, 2, $80, 0)
EndProcedure

;
; Opens an existing file or creates a new file.
;
Procedure fopen(filename.s, filemode)
  ProcedureReturn CreateFile_(filename, filemode, 0, 0, 4, $80, 0)
EndProcedure

;
; Closes a file.
;
Procedure fclose(filehandle)
  ProcedureReturn CloseHandle_(filehandle)
EndProcedure

;
; Determines if the end-of-file has reached.
;
Procedure feof(filehandle)
  If (SetFilePointer_(filehandle, 0, 0, 1) < GetFileSize_(filehandle, 0))
    tempeof = #False
  Else
    tempeof = #True
  EndIf
  ProcedureReturn tempeof
EndProcedure

;
; Reads file into a memory buffer.
;
Procedure fread(filehandle, *filebuffer, bufferlength)
  tempsize = 0
  tempbuff.s = Space(bufferlength)
  If ReadFile_(filehandle, tempbuff, bufferlength, @tempsize, 0)
    CopyMemory(@tempbuff, *filebuffer, bufferlength)
  EndIf
  ProcedureReturn tempsize
EndProcedure

;
; Writes the memory buffer to a file.
;
Procedure fwrite(filehandle, *filebuffer, bufferlength)
  tempsize = 0
  WriteFile_(filehandle, *filebuffer, bufferlength, @tempsize, 0)
  ProcedureReturn tempsize
EndProcedure

;
; Reads a line of text from a file.
;
Procedure.s freadln(filehandle)
  Define tempsize, tempcrlf, temppos
  tempbuff.s = Space(#FILE_BUFFERSIZE)
  filebuffer.s = ""
  temppos = SetFilePointer_(filehandle, 0, 0, 1)
  While temppos < GetFileSize_(filehandle, 0) And ReadFile_(filehandle, tempbuff, #FILE_BUFFERSIZE, @tempsize, 0)
    tempcrlf = FindString(tempbuff, #FILE_NEWLINE, 1)
    If tempcrlf > 0
      tempbuff = Left(tempbuff, tempcrlf - 1)
      Break
    Else
      filebuffer = filebuffer + tempbuff
    EndIf
  Wend
  filebuffer = filebuffer + tempbuff
  tempsize = temppos + Len(filebuffer) + Len(#FILE_NEWLINE)
  temppos = GetFileSize_(filehandle, 0)
  If tempsize > temppos
    filebuffer = Trim(filebuffer)
    tempsize = temppos
  EndIf
  SetFilePointer_(filehandle, tempsize, 0, 0)
  ProcedureReturn filebuffer
EndProcedure

;
; Writes a line of text to a file with a new line.
;
Procedure fwriteln(filehandle, filebuffer.s)
  Define tempsize
  filebuffer = filebuffer + #FILE_NEWLINE
  WriteFile_(filehandle, filebuffer, Len(filebuffer), @tempsize, 0)
  ProcedureReturn tempsize
EndProcedure

;
; Moves the file pointer to the offset relative from position.
;
Procedure fseek(filehandle, fileoffset, fileposition)
  ProcedureReturn(SetFilePointer_(filehandle, fileoffset, 0, fileposition))
EndProcedure

;
; Returns the position of the file pointer.
;
Procedure ftell(filehandle)
  ProcedureReturn(SetFilePointer_(filehandle, 0, 0, 1))
EndProcedure

;
; Returns the size of a file.
;
Procedure fsize(filehandle)
  ProcedureReturn GetFileSize_(filehandle, 0)
EndProcedure
FileData.pb

Code: Select all

XIncludeFile "Files.pbi"

xlong = 126210
xword.w = 2000
xbyte.b = 54
xfloat.f = 43.6   ; this returns a strange value so don't get shocked... it is not the fault of the library... ;)

ph = fcreate("C:\TEMP\VARIOUS.txt", #FILE_MODE_WRITE)
fwrite(ph, @xlong, SizeOf(xlong))
fwrite(ph, @xword, SizeOf(xword))
fwrite(ph, @xbyte, SizeOf(xbyte))
fwrite(ph, @xfloat, SizeOf(xfloat))
fclose(ph)

ph = fopen("C:\TEMP\VARIOUS.txt", #FILE_MODE_READ)
fread(ph, @xlong, SizeOf(xlong))
Debug xlong
fread(ph, @xword, SizeOf(xword))
Debug xword
fread(ph, @xbyte, SizeOf(xbyte))
Debug xbyte
fread(ph, @xfloat, SizeOf(xfloat))
Debug xfloat
fclose(ph)
FileRandom.pbi

Code: Select all

XIncludeFile "Files.pbi"

Structure recstruct
  name.b[32]
  add.b[64]
  tel.i
EndStructure
rec.recstruct

ph = fcreate("C:\TEMP\ADDBOOK.txt", #FILE_MODE_WRITE)

PokeS(@rec\name, "Cute Boy", SizeOf(rec\name))
PokeS(@rec\add, "Penang", SizeOf(rec\add))
rec\tel = 100000
fwrite(ph, @rec, SizeOf(rec))

PokeS(@rec\name, "Small John", SizeOf(rec\name))
PokeS(@rec\add, "KL", SizeOf(rec\add))
rec\tel = 200000
fwrite(ph, @rec, SizeOf(rec))

PokeS(@rec\name, "Pretty", SizeOf(rec\name))
PokeS(@rec\add, "Kulim", SizeOf(rec\add))
rec\tel = 100000
fwrite(ph, @rec, SizeOf(rec))

fclose(ph)

ph = fopen("C:\TEMP\ADDBOOK.txt", #FILE_MODE_READ)

fread(ph, @rec, SizeOf(rec))
buff$ = PeekS(@rec\name, SizeOf(rec\name))
Debug buff$
buff$ = PeekS(@rec\add, SizeOf(rec\add))
Debug buff$
Debug rec\tel

fread(ph, @rec, SizeOf(rec))
buff$ = PeekS(@rec\name, SizeOf(rec\name))
Debug buff$
buff$ = PeekS(@rec\add, SizeOf(rec\add))
Debug buff$
Debug rec\tel

fread(ph, @rec, SizeOf(rec))
buff$ = PeekS(@rec\name, SizeOf(rec\name))
Debug buff$
buff$ = PeekS(@rec\add, SizeOf(rec\add))
Debug buff$
Debug rec\tel

; read record 2 again... (rec 2 is rec 1 because records start at 0)
#recno = 1
fseek(ph, #recno * SizeOf(rec), #FILE_SEEKPOS_BEGIN)

fread(ph, @rec, SizeOf(rec))
buff$ = PeekS(@rec\name, SizeOf(rec\name))
Debug buff$
buff$ = PeekS(@rec\add, SizeOf(rec\add))
Debug buff$
Debug rec\tel

fclose(ph)
here's an advantage where this library can come in handy. enclosed is the equivalent for PB library...

FileSeqText.pbi

Code: Select all

XIncludeFile "Files.pbi"

; C:\TEMP\TEST.txt contains...
; This is a test line #1.
; This is a test line #2.
; Delete this line.
; This is a test line #3.
; This is a test line #4.
;

ihandle = fopen("C:\TEMP\TEST.txt", #FILE_MODE_READ)
ohandle = fcreate("C:\TEMP\NEW.txt", #FILE_MODE_WRITE)
While feof(ihandle) = 0
  b$ = freadln(ihandle)
   Debug "[" + b$ + "]"
  If FindString(LCase(b$), "delete", 1) <> 0
    Debug "not moved"
  Else
    fwriteln(ohandle, b$)
  EndIf
Wend
fclose(ohandle)
fclose(ihandle)