Filesystem

Just starting out? Need help? Post your questions and find answers here.
Zooker
User
User
Posts: 22
Joined: Sun Apr 27, 2003 1:46 am
Location: So.Illinois USA

Filesystem

Post 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!! :?
It took 73 years for me to get this Stupid!
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Post 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...
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Post 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) 
Zooker
User
User
Posts: 22
Joined: Sun Apr 27, 2003 1:46 am
Location: So.Illinois USA

Filesystem

Post 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
It took 73 years for me to get this Stupid!
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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!
oh... and have a nice day.
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Post 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$)
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post 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.
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
harkon
Enthusiast
Enthusiast
Posts: 217
Joined: Wed Nov 23, 2005 5:48 pm

Post 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.
Missed it by that much!!
HK
Post Reply