Seite 2 von 5

Verfasst: 29.07.2009 13:46
von ts-soft
Einsatzzwecke gibts aber auch heute noch und man kann beim entwickeln
solcher Algorithm auch einige Grundlagen bezüglich File und Memory ver-
stehen lernen :wink:

Z.B. Leveldaten könnten eine fixe Größe haben und nacheinander benötigt
werden, eine Datenbank hätte hier zuviel unnötigen Overhead.

Ansonsten stimme ich euch natürlich zu.

Verfasst: 29.07.2009 14:08
von mikstart

Code: Alles auswählen

Structure RecSet
  Name.s[20]
  Price.q
  Units.l
EndStructure

Dim DataBase.RecSet(800)


; Datensatz Suchen
FileSeek( #DB, RecordNumber * SizeOf( RecSet ) )

; Datensatz schreiben
WriteString( #DB, DataBase(RecordNumber)\Name  )
WriteQuad  ( #DB, DataBase(RecordNumber)\Price )
WriteLong  ( #DB, DataBase(RecordNumber)\Units )

; Datensatz lesen
DataBase(RecordNumber)\Name  = ReadString( #DB )
DataBase(RecordNumber)\Price = ReadQuad  ( #DB )
DataBase(RecordNumber)\Units = ReadLong  ( #DB )

; komplette Tabelle schreiben
WriteData( #DB, @DataBase(), NumberOfRecords * SizeOf( RecSet ) )

; komplette Tabelle lesen
ReadData( #DB, @DataBase(), NumberOfRecords * SizeOf( RecSet ) )
sieht nicht schlecht aus.

ich muss doch noch CreateFile(#DB, DataBase.RecSet(800)). geht aber nicht. der hat immer was an db auszusetzen, ob ich mit create oder ohne. was hat das mit #DB auf sich? db wird ja wohl für datenbank stehen, aber wie muss ich definieren das dieses beispiel läuft.


@Kiffi und Kaeru Gaman

lasst mich erst mal laufen lernen und die ganzen grund begriffe von pure basic verstehen, in ein paar monaten können wir mal über sql reden.

gruss mik

Verfasst: 29.07.2009 14:12
von Kaeru Gaman
@ts
im Prinzip ja, aber...

die Anforderung, gleich groß portionierte Leveldaten sequenziell zu laden,
halte ich für einen extremen Sonderfall.

normalerweise würde man Levelweise vorgehen, da lädt man einen ganzen Level auf einen Rutsch,
was bei heutigen Hauptspeichergrößen kein Problem darstellt.
Außerdem können hierbei Level unterschiedlich groß sein und unterschiedlich viel Inhalt haben.

wenn man die Level nicht in getrennten Files haben will, steht man wieder vor der Datenbank-Frage,
weil nicht nur Level unterschiedlich groß sein können,
sondern auch gleiche Objekte in unterschiedlichen Leveln bzw. Sektoren vorkommen können.

Natürlich ist es grundsätzlich gut zu wissen wie ein RandomAccessFile funktioniert,
aber die tatsächlichen Anwendungen sind heutzutage so gut wie ausgestorben.

im vorliegenden Fall soll es wohl um eine Stammdaten-Verwaltung gehen, das ist das klassische Schulbeispiel für SQL-Benutzung.

Verfasst: 29.07.2009 14:16
von Kaeru Gaman
mikstart hat geschrieben:ich muss doch noch CreateFile(#DB, DataBase.RecSet(800)). geht aber nicht. der hat immer was an db auszusetzen, ob ich mit create oder ohne. was hat das mit #DB auf sich? db wird ja wohl für datenbank stehen, aber wie muss ich definieren das dieses beispiel läuft.
das ist nur ein snippet das das Prinzip zeigen soll.

#DB ist eine Konstante, deine momentane FileNummer, setz die am Anfang einfach auf Null.

Code: Alles auswählen

#DB = 0
und als Name bei CreateFile musst du latürnich einen Datei-Namen angeben

Code: Alles auswählen

CreateFile(#DB, DataBase.RecSet(800))
ist ja absolut abenteuerlich!

bitte doch auch ein wenig die Help lesen und nicht Buchstaben ins Blaue werfen.

Verfasst: 29.07.2009 17:58
von mikstart
du wirst lachen, ich hab die hilfe ständig offen nur manchmal versteh ich nur bahnhof. hatte nur auf die anwendungsmöglichkeiten von create geschaut und kam dann auf das abenteuerliche. dabei steht ganz oben sogar fett "Ergebnis = OpenFile(#Datei, DateiName$)"

nun hab ich folgendes:

Code: Alles auswählen

Structure RecSet 
  
  Name.s[20] 
  Price.q 
  Units.l 
EndStructure 

Dim DataBase.RecSet(900)

#DB = 1
datei$ = "dat"

CreateFile(#DB, datei$)
CloseFile(#DB)


OpenFile(#DB, Datei$)

For RecordNumber = 100 To 900
units.l = units.l +1

; Datensatz schreiben 
WriteString( #DB, DataBase(RecordNumber)\Name  ) 
WriteQuad  ( #DB, DataBase(RecordNumber)\Price ) 
WriteLong  ( #DB, DataBase(RecordNumber)\Units ) 
Next RecordNumber

CloseFile(#DB)
die recordnumber ist doch die datensatz nummer oder?
dann müsste er doch praktisch in der dat von 100 bis 900 stehen.
spätestens bei units.l müsste in der dat 1 bis 800 stehen haben.
aber ich sehe nichts wenn ich dat mit den text editor aufmache.
die datei dat hat aber 9,38 kb.

und wie kan ich das auf den bildschirm bringen wenn ich mit ReadString ausgelesen habe, mit print geht das irgendwie nicht.

gruss mik

Verfasst: 29.07.2009 18:10
von ZeHa
ts-soft spricht über das Speichern von Leveldaten... daß ich das noch erleben darf :bounce:

Verfasst: 29.07.2009 19:44
von H.Brill
Hallo,
Datensatznummer gibt es so nicht.
Du kannst dir aber mit ein wenig Aufwand
das ganze als Proceduren schreiben.
Dazu brauchst du die Länge der Structure
und die PB Funktionen Lof() und Fileseek().
Also :
1. Datensatz auf Position 0
2. Datensatz auf SizeOf(deineStructure)
usw.

Damit kann man leicht errechnen, wo Datensatz x
liegt, bzw. wo man mit Fileseek() hinspringen muß,
um ihn zu überschreiben.

PS : Wenn es nicht zuviele Datensätze sind, kann man
auch die Preference benutzen. Einfach die Gruppen
(Ergebnis = PreferenceGroup(Name$)) durchnummerieren,
also [1], [2] usw und dazwischen deine Daten.
z.B:
[1]
Artikel = "Festplatte"
Stueck = 10
Preis = 50.00
[2]
.....
Geht dann sehr einfach mit WritePreferenceString,
WritePrefernceInteger und WritePrefenceFloat bzw.
ReadPreference....

Alles weitere schaue in der Hilfe.

Verfasst: 29.07.2009 21:49
von mk-soft
Habe mal Put und Get nachgebaut... Ist aber erst mal ein anfang.

Code: Alles auswählen



; *****************************************************************************

#FileDB = 0
Global FileMax

Procedure OpenDB(name.s, size)

  If OpenFile(#FileDB, name)
    FileMax = Lof(#FileDB)
    FileMax / size
    FileMax - 1
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure


Procedure CloseDB()

  If IsFile(#FileDB)
    CloseFile(#FileDB)
  EndIf
EndProcedure

Procedure GetDB(id, *pdata, size)
  
  Protected pos, len
  
  If id > FileMax
    ProcedureReturn #False
  EndIf
  
  pos = id * size
  FileSeek(#FileDB, pos)
  len = ReadData(#FileDB, *pdata, size)
 
  If len = size
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure

Procedure PutDB(id, *pdata, size)

  Protected pos, len
  
  If id > FileMax + 1
    ProcedureReturn #False
  EndIf
  
  pos = id * size
  FileSeek(#FileDB, pos)
  len = WriteData(#FileDB, *pdata, size)
  If len = size
    FileMax + 1
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure

; *****************************************************************************

Structure udtData
  Name.s{20}
  Price.d
  Units.l
EndStructure

Global dataOut.udtData, dataIn.udtData

Debug "Open DB"
If OpenDB("TestDB.DAT", SizeOf(udtData))
  Debug "Ok."
Else
  Debug "Error Open"
  End
EndIf

Debug "Put..."

For id = 0 To 10
  With dataOut
    \Name = "Name ID " + Str(id)
    \Price = 10.5 + id
    \Units = 100 + id
  EndWith
  If PutDB(id, dataOut, SizeOf(udtData))
    Debug "PutDB Ok."
  Else
    Debug "PutDB Error"
  EndIf
Next

Debug "Change..."
  id = 5
  With dataOut
    \Name = "Hallo Welt: " + Str(id)
    \Price = 99.8
    \Units = 1000 
  EndWith
  If PutDB(id, dataOut, SizeOf(udtData))
    Debug "PutDB Ok."
  Else
    Debug "PutDB Error"
  EndIf

Debug "Get..."
For id = 0 To 11
  If GetDB(id, dataIn, SizeOf(udtData))
    With dataIn
      Debug "ID     : " + Str(id)
      Debug "Name   : " + \Name
      Debug "Price  : " + StrD(\Price)
      Debug "Units  : " + Str(\Units)
    EndWith
  Else
    Debug "GetDB Error"
  EndIf
Next

CloseDB()

FF :wink:

Verfasst: 30.07.2009 08:29
von mikstart
mk-soft hat geschrieben:Habe mal Put und Get nachgebaut... Ist aber erst mal ein anfang.

Code: Alles auswählen

[/quote]


wow, hab gar nicht gewusst das man so viel code dafür braucht.

1000 dank

gruss mik

Verfasst: 30.07.2009 09:02
von mk-soft
Das ist doch nicht viel Code :roll:

Lof(...) funktioniert doch richtig. Habe mal den Code überarbeitet

Code: Alles auswählen

; *****************************************************************************

#FileDB = 0

Procedure OpenDB(name.s)

  If OpenFile(#FileDB, name)
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
 
EndProcedure


Procedure CloseDB()

  If IsFile(#FileDB)
    CloseFile(#FileDB)
  EndIf
EndProcedure

Procedure GetDB(id, *pdata, size)
 
  Protected max, pos, len
  
  If IsFile(#FileDB) = #False
    ProcedureReturn #False
  EndIf
  
  max = Lof(#FileDB)
  max / size
  max - 1
  
  If id > max
    ProcedureReturn #False
  EndIf
 
  pos = id * size
  FileSeek(#FileDB, pos)
  len = ReadData(#FileDB, *pdata, size)
 
  If len = size
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
 
EndProcedure

Procedure PutDB(id, *pdata, size)

  Protected max, pos, len
  
  If IsFile(#FileDB) = #False
    ProcedureReturn #False
  EndIf
  
  max = Lof(#FileDB)
  max / size
  
  If id > max
    ProcedureReturn #False
  EndIf
 
  pos = id * size
  FileSeek(#FileDB, pos)
  len = WriteData(#FileDB, *pdata, size)
  If len = size
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
 
EndProcedure

; *****************************************************************************

Structure udtData
  Name.s{20}
  Price.d
  Units.l
EndStructure

Global dataOut.udtData, dataIn.udtData

Debug "Open DB"
If OpenDB("TestDB.DAT")
  Debug "Ok."
Else
  Debug "Error Open"
  End
EndIf

Debug Lof(#FileDB)

Debug "Put..."

For id = 0 To 10
  With dataOut
    \Name = "Name ID " + Str(id)
    \Price = 10.5 + id
    \Units = 100 + id
  EndWith
  If PutDB(id, dataOut, SizeOf(udtData))
    Debug "PutDB Ok."
  Else
    Debug "PutDB Error"
  EndIf
Next

Debug "Change..."
  id = 5
  With dataOut
    \Name = "Hallo Welt: " + Str(id)
    \Price = 99.8
    \Units = 1000
  EndWith
  If PutDB(id, dataOut, SizeOf(udtData))
    Debug "PutDB Ok."
  Else
    Debug "PutDB Error"
  EndIf

Debug "Get..."
For id = 0 To 11
  If GetDB(id, dataIn, SizeOf(udtData))
    With dataIn
      Debug "ID     : " + Str(id)
      Debug "Name   : " + \Name
      Debug "Price  : " + StrD(\Price)
      Debug "Units  : " + Str(\Units)
    EndWith
  Else
    Debug "GetDB Error"
  EndIf
Next

CloseDB()
FF :wink: