Page 1 of 1

Filesystem

Posted: Fri Jan 02, 2009 6:32 am
by Zooker
The filesystem in PB seems more difficult to use in comparison to the Basic Random read & write put & get routines. Would it be possible to
make files all strings and use a val or other similar comand to change the
fields that need to be changed to numbers. I am re-writing a program I had written in Basic PDS tto a windows program? Purebasic seems to be the only Basic that works in Vista 64 at all and I sure would like to be able to make it work now that I've bought it!! :?

Posted: Fri Jan 02, 2009 6:57 am
by citystate
I'm not sure what you mean, Zooker

by "making files all strings" do you mean, read the data from the file as a string? if so, is this snippet the kind of thing you're looking for?

Code: Select all

if openfile(0,filename$)
  while eof(0)=0
    s$ = readstring(0)
    ;<insert string handling code here>
    debug s$
  wend
  closefile(0)
endif
I'm sure you'll find PureBasic up to the task...

Posted: Fri Jan 02, 2009 7:04 am
by idle
Is this what you need?

oh well you got both read and write! :lol:

Code: Select all

somelong.l = 123456

strOut.s ="Some test data" + Chr(13) + Chr(10) + "and a new line" + Chr(13) + Chr(10)
strOut + "some numbers " + Str(somelong) + " some binary " + RSet(Bin($FF),8) + " hex " + Hex(255) + Chr(13) + Chr(10) 
sfile.s = "C:\test.text"

OpenFile(1,sfile)
 ;FileSeek(1,Lof(1)) ;uncomment to append file    
 WriteData(1,@strOut,Len(strOut))
CloseFile(1) 

Filesystem

Posted: Fri Jan 02, 2009 6:21 pm
by Zooker
Something More like this
Structure
Name as string
Age as string
Job as string
Height as string
end structure
Writeline Name |
WriteLine Age |> Basic did al this by saying Put #1 Structure Basically
WriteLine Job |
WriteLine Height |
Print Val(Age) as Number ; Changes string to Number

Posted: Fri Jan 02, 2009 6:40 pm
by Kaeru Gaman
you can use fixlength strings to build the structure.
use WriteString to put them into the file.

you could also use WriteData and put a complete structured Array in one into a file.

... but after all, there is no gain in using strings only for data format.
a Quad stores numbers up to 9223372036854775807 in 8byte.
as a string you need 20 byte in ANSI resp. 40 byte in Unicode to store such a number.
Basic did al this by saying Put #1 Structure Basically
"Basic" is not a Produkt name!
PureBasic is also a BASIC dialect.
if you want to compare different Basics, please state their name!

Posted: Fri Jan 02, 2009 9:12 pm
by blueb
Here's a small sample of a PureBasic record....

Code: Select all

Structure Layout
  Name.s{50}        ; string max. size = 50 chars
  Age.l                  ; type is a LONG
  Job.s{50}
  Height.s{20}
EndStructure

Dim Rec.Layout(50) ; Create enough room for 50 records


Rec(0)\Name = "Barry Smith" 
Rec(0)\Age = 34
Rec(0)\Job = "Account Manager"
Rec(0)\Height = "5Ft 6"

Rec(1)\Name = "Bob Jackson" 
Rec(1)\Age = 58
Rec(1)\Job = "CEO"
Rec(1)\Height = "6 Ft 0 In"


Text$ = Rec(1)\Name + "'s  age is: " + Str(Rec(1)\age )

MessageRequester("Find the second record", Text$)

Posted: Mon Jan 05, 2009 12:56 am
by pdwyer
Zooker,

I'm not sure if this question is answered or not to your satisfaction. There is some code in the tips section that people have written to handle record like reads and writes to files.

Personally though, I think you would be better served with a little SQLite DB, Using SQLite in your app adds about 350k to the exe size but the data files created are tiny and it gives you more query power, handles your record updates and deletions and is scalable should your app get bigger.

Posted: Mon Jan 05, 2009 8:22 pm
by harkon
Zooker,

In the following code is a copy of the QB help example for the "PUT" function. I have included a substitute with procedures to somewhat emulate the behavior of the QB functions. I have used this sort of file and record I/O before to access data files created by legacy applications. As pdwyer mentioned, I would move to using a SQLite DB. It is miles ahead of the way QB used to do this, and is scalable to very large record numbers. As you are recoding anyway, it really makes sense. If you want to play though to get familiar with QB, I hope the attached code helps.

Code: Select all

;---------- Code from QB "PUT" help example ---------
; ' Read a name and a test score from the console.
; ' Store each name and score as a record in a
; ' random-access file.
; 
; ' Define record fields.
; TYPE TestRecord
;    NameField  As STRING * 20
;    ScoreField As SINGLE
; End TYPE
; 
; ' Open the test data file.
; Dim FileBuffer As TestRecord
; OPEN "TESTDAT.DAT" For RANDOM As #1 LEN = Len(FileBuffer)
; 
; ' Read pairs of names and scores from the console.
; 
; CLS    ' Clear screen
; I = 0
; DO
;    I = I + 1
;    INPUT "Name ? ", FileBuffer.NameField
;    INPUT "Score? ", FileBuffer.ScoreField
;    INPUT "-->More (y/n)? ", Resp$
;    PUT #1, I, FileBuffer
; LOOP Until UCASE$(MID$(Resp$, 1, 1)) = "N"
; 
; PRINT I; " records written."
; 
; CLOSE #1


;------------- start of PB code -----------------
;setup structure
Structure TestRecord
  NameField.s{20}
  ScoreField.f
EndStructure

; Open the test data file.
Dim FileBuffer.TestRecord(0)
OpenFile(1,"C:\Program Files\PureBasic\Projects\Test\TESTDAT.DAT")
Global TestRecLen.w=SizeOf(TestRecord)

; Procedures to make this as QB as possible
Procedure QBPut(Filenum.w,RecordNum.w,*recordpointer)
  FileSeek(FileNum,(RecordNum-1)*TestRecLen)
  WriteData(Filenum,*recordpointer,TestRecLen)
EndProcedure

Procedure.s QBInput(InputString.s)
  Print(Inputstring)
  ProcedureReturn Input()
EndProcedure

;Open a console and clear it
OpenConsole()
EnableGraphicalConsole(1)
ClearConsole()

I=0
Repeat
  I=I+1  
  FileBuffer(0)\NameField=QBInput("Name ? ")
  FileBuffer(0)\Scorefield=ValF(QBInput("Score ? "))
  Resp$=QBInput("-->More (y/n)? ")
  QBPut(1,I,@FileBuffer(0))
Until UCase(Resp$)="N"
PrintN(Str(I) + " records written")

CloseFile(1)

;this will keep the console open until you hit a key
Repeat
  Delay(100)
Until Inkey()<>""
The absolute beauty of PB is that a whole lot can be accomplished without a great deal of extra coding. You shoud be aware though that in PB strings are null terminated. In QB you could store chr$(00) in a string, in PB that will terminate the string and there will be no data after that. You will need to use memory buffers to store binary data. This make PB far more efficient as string handling tends to be slow in most languages. Directly manipulating memory is far more efficient.

Post back if you have any questions.



Edited
moved procs to after "Global TestRecLen" as otherwise the procs didn 't see the value.