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
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.
und als Name bei CreateFile musst du latürnich einen Datei-Namen angeben
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

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

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
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
