[GELÖST] ReadBank - Offset-Feld?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] ReadBank - Offset-Feld?

BeitragDi, Mai 21, 2013 18:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
ich habe (jetzt wirklich) ein Problem mit Banks: Wenn ich mit ReadBank Daten aus einer Datei in eine Bank laden will, weiß ich absolut nicht, was ich in das Feld "offset" packen soll. Gebe ich 0 ein, gibt es zwar keinen Fehler beim compilieren, jedoch wird auch nicht das richtige in die Bank geschrieben. Schreibe ich den Dateizeiger rein, ab dem die Daten stehen, gibt es einen "Illegal Bank Offset" - Fehler.
Ich weiß nicht, was ich noch eintragen könnte...

hoffe ihr könnt mir helfen...
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Do, Mai 23, 2013 12:27, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragDi, Mai 21, 2013 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Geh sicher, dass du offset in Bytes angibst, diesen richtig berechnet hast und auch genügend Platz in der Bank ist, für die Daten.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

ZEVS

BeitragMi, Mai 22, 2013 16:26
Antworten mit Zitat
Benutzer-Profile anzeigen
ReadBank( bank:TBank,stream:TStream,offset,count ) tut folgendes: Es liest sich count Bytes aus dem Stream und kopiert sie in die Bytes von offset bis offset+count-1 der Bank hinein. Wenn du also die ganze Bank mit deinen Daten füllen willst, ist offset=0 richtig. Allerdings muss der Stream richtig eingestellt sein. Wenn ich es richtig verstanden habe, beginnen die Daten für die Bank nicht direkt am Anfang der Datei, sondern etwas später (nach einem Header). ReadBank fängt aber dort an zu lesen und zu kopieren, wo der Dateizeiger steht. Daher musst du dafür sorgen, dass der Dateizeiger genau auf dem Anfang der Daten steht, wenn du sie einlesen willst. Nutze, wenn es nicht so ist, SeekStream oder TStream.Seek.

ZEVS
 

CO2

ehemals "SirMO"

BeitragDo, Mai 23, 2013 12:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Antworte und entschuldigung, dass ich jetzt erst antworte.

@ Xeres:
Wenn ich wüsste wofür offset ist, kann ich das machen Wink Bei google habe ich nichts zu dem Thema gefunden und die BMax - Hilfe ist da auch nicht gerade hilfreich...

@ ZEVS:
Ok, danke... Werde mal auf der Basis was versuchen. Aber wofür gibt es dann überhaupt das offset - Feld, wenn nur 0 eingetragen werden kann?

PS: Ich tagge das Thema mal als [GELÖST]...
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Xeres

Moderator

BeitragDo, Mai 23, 2013 18:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie kommst du darauf, offset könne nur 0 sein?
Nochmal deutlich: Der Offset gibt an, wie viele Bytes übersprungen werden, bevor begonnen wird zu lesen.
Wenn man mit Dateien/Streams arbeitet, muss man auch darauf achten, nicht mehr zu lesen, als Daten vorhanden sind. In Streams wird der Offset nur intern gespeichert und kann mit Seek manuell gesetzt werden.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Holzchopf

Meisterpacker

BeitragDo, Mai 23, 2013 18:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Xeres hat Folgendes geschrieben:
Der Offset gibt an, wie viele Bytes übersprungen werden, bevor begonnen wird zu lesen.

Und ich behaupte: Offset gibt an, ab welcher Position in der Bank geschrieben wird, wie bei allen Bank-Befehlen Rolling Eyes Oder verstehe ich dich jetzt falsch? Confused

Los, Mod-Fight! /me holt schon mal das Planschbecken mit dem Schlamm

Wer schreibt den Code, der meine Aussage beweist?

@CO2: Wenn's nicht klappt, wenn du den Zeiger der Daten reinschreibst, wär's gut zu wissen, wie gross die Bank ist, die du erstellst, wie die Datei aufgebaut ist und ab welcher Position du lesen möchtest. Ist dein Problem wirklich schon gelöst?

mfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Xeres

Moderator

BeitragDo, Mai 23, 2013 18:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn mir der verehrte Herr Holzchopf erklären kann, wie er mit ReadBank etwas in eine Bank schreiben will, bleibe ich den Rest meines Lebens im Planschbecken.

Aber ansonsten möchte ich mir anschließen; gut möglich, dass wir aneinander vorbei reden und Code würde ganz eindeutig zeigen, wo das eigentliche Problem liegt.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Holzchopf

Meisterpacker

BeitragDo, Mai 23, 2013 18:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Die unfehlbare BMax-Doku hat Folgendes geschrieben:
Read bytes from a Stream to a Bank

Bittesehr Wink
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

CO2

ehemals "SirMO"

BeitragDo, Mai 23, 2013 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, ich wollte jetzt keinen Mod-Fight hervorrufen Very Happy

Also das Problem an sich ist gelöst - ich weiß ungefähr, wofür das offset-Feld ist. Trotzdem werden die Daten falsch ausgelesen...

Hier der Code:
Speichern des Paketes BlitzMax: [AUSKLAPPEN]
Function SavePackage(Request:Int = True)
If(Request = 1)
Local SaveFile:String = RequestFile("Paket speichern unter...", "Datenpaket (*.PAC):PAC", True)
If(SaveFile <> "")
SAVEPATH = SaveFile
EndIf
EndIf

Local Archive:TStream = WriteFile(SAVEPATH) ' SAVEPATH: Speichert den zuerst angegeben Pfad, um Schnellspeichern zu ermöglichen
If(Archive = Null)
Notify("SCHWERWIEGENDER FEHLER!", True)
Else
WriteLine(Archive, "%PAC" + Replace(Version, ".", "") + "%") ' Version: String-"Konstante", momentan 1.0
WriteLine(Archive, "[REG]")

For Local x:Int = 0 To (CountGadgetItems(FileList) - 1) ' Filelist: Das ganze ist ein Windowsfenster. Filelist ist eine Listbox, in der die Pfade angegeben sind.
WriteLine(Archive, StripDir(GadgetItemText(FileList, x)))
WriteInt(Archive, FileSize(GadgetItemText(FileList, x)))
Next

WriteLine(Archive, "[DAT]")

Local TempSrcFile:TStream

For x = 0 To (CountGadgetItems(FileList) - 1)
TempSrcFile = ReadFile(GadgetItemText(FileList, x))
If(TempSrcFile = Null)
DeleteFile(SAVEPATH)
Notify("SCHWERWIEGENDER FEHLER!", True)
Exit
EndIf

Repeat
WriteByte(Archive, ReadByte(TempSrcFile))
Until Eof(TempSrcFile)
CloseFile(TempSrcFile)
Next
Notify("Speichern fertiggestellt!")
CloseFile(Archive)
EndIf
End Function


Hier die Funktion zum Auslesen einer Datei BlitzMax: [AUSKLAPPEN]
Function LoadFileFromPac:TBank(PAC:TStream, FileName:String)
Rem
Aufbau:
%PAC10%
[REG]
Dateiname
Dateigröße
...
[DAT]
Dateiinhalt
...
End Rem


If(PAC <> Null)
SeekStream(PAC, 0)
If(ReadLine(PAC) <> "%PAC10%") ' Versions-Check
Print("PACERR: Wrong PAC-Version found!")
Return Null
EndIf
If(ReadLine(PAC) <> "[REG]") ' Struktur-Check
Print("PACERR: Wrong Datastructure found!")
Return Null
EndIf

Local ErrCode:Int = 0 ' 0 = kein Fehler, 1 = EOF, 2 = Ende des Dateiregisters
Local SeekSize:Int = 0 ' Speichert die zu gehenden Bytes

Local SearchFileName:String = ""
Local SearchFileSize:Int = 0

Repeat
SearchFileName = ReadLine(PAC)
SearchFileSize = ReadInt(PAC)

SeekSize = SeekSize + SearchFileSize ' Positionen immer aufaddieren
If(Eof(PAC))
ErrCode = 1
Exit
EndIf
If(SearchFileName = "[DAT]")
ErrCode = 2
Exit
EndIf
Until SearchFileName = FileName
SeekSize = SeekSize - SearchFileSize ' Zum schluss einmal die Größe der gesuchten Datei wieder abziehen

If(ErrCode = 0) ' Nur wenn kein Fehler...
Local TempString:String = "" ' Zunächst bis zum Datenteil springen
Repeat
TempString = ReadLine(PAC)
ReadInt(PAC)
Until TempString = "[DAT]"

SeekStream(PAC, (StreamPos(PAC) + SeekSize)) ' Von da an bis zum Dateianfang der gesuchten Datei springen.

Local ReturnMe:TBank = CreateBank(SearchFileSize)

ReadBank(ReturnMe, PAC, 0, SearchFileSize)

Return ReturnMe
Else
Return Null
EndIf
Else
Return Null
EndIf
End Function
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

ZEVS

BeitragDo, Mai 23, 2013 21:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Du sagst, das Auslesen klappt nicht, also gehe ich davon aus, dass das Schreiben fehlerfrei verläuft. Es wäre natürlich interessant zu wissen, welche "falschen" Daten ausgelesen werden. Der genaue Sinn von BlitzMax: [AUSKLAPPEN]
			Repeat
TempString = ReadLine(PAC)
ReadInt(PAC)
Until TempString = "[DAT]"

erschließt sich mit nicht, wenn ich es richtig verstanden habe, werden alle Zeilen bis "[DAT]" übersprungen. Aber wozu dann das ReadInt? Der Rest sieht in Ordnung aus, soweit ich das Dateiformat verstanden habe. Im Zweifelsfall: DebugLog ist dein Freund. Gebe dir doch mal die Streamposition, SeekSize und SearchFileSize aus und vergleiche mit dem, was du erwarten würdest.

ZEVS
 

CO2

ehemals "SirMO"

BeitragDo, Mai 23, 2013 22:49
Antworten mit Zitat
Benutzer-Profile anzeigen
@ ZEVS:
Da die Daten im [REG] - Teil so abgespeichert werden, dass zuerst der Dateiname und dann die Dateigröße geschrieben wird, muss ich natürlich - Wenn ich im [REG] - Teil die entsprechende Datei mit der dazugehörigen Größe gefunden habe - den restlichen Teil bis zum [DAT] - Teil überspringen, Die Dateinamen muss ich abspeichern, da ich ja kontrollieren muss, ob ich den [DAT] - Teil erreicht habe. Das ReadInt() ließt dann einfach Temporär die "Dateigröße" aus, welche ich natürlich nicht brauche und deshalb nicht abspeichere.
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Holzchopf

Meisterpacker

BeitragDo, Mai 23, 2013 23:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Aaaalso. Dein Datei-aufbau ist klar: nach [DAT] folgen nahtlos Dateiinhalte (unschwer zu erkennen am Kommentar, top! Smile (hab's aber auch noch mal im Speichern-Code nachgeschaut Wink )), also musst du beim Auslesen auch nahtlos nach [DAT] die Daten lesen. Um quasi das letzte ReadInt() rückgängig zu machen, könntest du dies entweder beim setzen des Zeigers - BlitzMax: [AUSKLAPPEN]
(StreamPos(PAC) + SeekSize - 4)
(4, weil ein Int vier Byte beansprucht), oder, eleganter, das ReadInt() direkt nur wenn nötig durchführen: BlitzMax: [AUSKLAPPEN]
			Repeat
TempString = ReadLine(PAC)
' Anfang der Datei-Inhalte erreicht
If TempStrin = "[DAT]"
Exit
' noch im [REG]-Teil, Dateigrösse auslesen/überspringen
Else
ReadInt(PAC)
EndIf
Forever


mfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

CO2

ehemals "SirMO"

BeitragDo, Mai 23, 2013 23:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, ja... Das hatte ich gar nicht gesehen Very Happy

Funktioniert!

Hier nochmal die funktionierende Version der LoadFileFromPac-Funktion sowie eine abgewandelte Version der SavePacFile-Funktion (Falls sie jemand braucht Very Happy ) BlitzMax: [AUSKLAPPEN]
Rem
Autor: Marius Otto
Datum: 23.05.2013
Referenz:
- Function SavePacFile:Int(Path:String, Files:TList)
-> Beschr.: Kreiert ein Datenpaket, mit allen Dateien, dessen Pfade in Files stehen, enthält.
-> Params: Path - String, Dateipfad
Files - TList, Alle Dateien, welche in das Paket eingebunden werden sollen als String in diese Liste speichern
-> Return: 1 = Fehlerfrei, 0 = Fehler
- Function LoadFileFromPac:TBank(PAC:TStream, FileName:String)
-> Beschr.: Extrahiert eine Datei aus dem Dateipaket
-> Params: PAC - TStream, DateiHANDLE des Datenpaketes
FileName - String, Dateiname der zu extrahierenden Datei
-> Return: NULL = Datei konnte nicht extrahiert werden, [TBANK] = Daten geladen
End Rem


Private
Global SAVEFUNCVERSION:String = "1.1"
Global READFUNCVERSION:String = "1.1"

Public
Function SavePacFile:Int(Path:String, Files:TList) ' Return: 0 = Misserfolg, 1 = Erfolg
Local PAC:TStream = WriteFile(Path)
If(PAC <> Null)
If(Files = Null)
Return 0
EndIf
WriteLine(PAC, "%PAC" + Replace(SAVEFUNCVERSION, ".", "") + "%") ' Version eintragen
WriteLine(PAC, "[REG]")
For Local x:String = EachIn Files
WriteLine(PAC, StripDir(x))
WriteInt(PAC, FileSize(x))
Next

WriteLine(PAC, "[DAT]")
Local TempSrcFile:TStream
For x = EachIn Files
TempSrcFile = ReadFile(x)
If(TempSrcFile = Null)
CloseFile(PAC)
DeleteFile(Path)
Return 0
EndIf
Repeat
WriteByte(PAC, ReadByte(TempSrcFile))
Until Eof(TempSrcFile)
CloseFile(TempSrcFile)
Next

CloseFile(PAC)
Return 1
Else
Return 0
EndIf
End Function

Function LoadFileFromPac:TBank(PAC:TStream, FileName:String)
If(PAC <> Null)
SeekStream(PAC, 0)
If(ReadLine(PAC) <> "%PAC" + Replace(READFUNCVERSION, ".", "") + "%") ' Versions-Check
Print("PACERR: Wrong PAC-Version found!")
Return Null
EndIf
If(ReadLine(PAC) <> "[REG]") ' Struktur-Check
Print("PACERR: Wrong Datastructure found!")
Return Null
EndIf

Local ErrCode:Int = 0 ' 0 = kein Fehler, 1 = EOF, 2 = Ende des Dateiregisters
Local SeekSize:Int = 0 ' Speichert die zu gehenden Bytes

Local SearchFileName:String = ""
Local SearchFileSize:Int = 0

Repeat
SearchFileName = ReadLine(PAC)
SearchFileSize = ReadInt(PAC)

SeekSize = SeekSize + SearchFileSize ' Positionen immer aufaddieren
If(Eof(PAC))
ErrCode = 1
Exit
EndIf
If(SearchFileName = "[DAT]")
ErrCode = 2
Exit
EndIf
Until SearchFileName = FileName
SeekSize = SeekSize - SearchFileSize ' Zum schluss einmal die Größe der gesuchten Datei wieder abziehen

If(ErrCode = 0) ' Nur wenn kein Fehler...
Local TempString:String = "" ' Zunächst bis zum Datenteil springen
Repeat
TempString = ReadLine(PAC)
If(TempString = "[DAT]")
Exit
EndIf
ReadInt(PAC)
Until Eof(PAC)
If(Eof(PAC))
Return Null
EndIf

SeekStream(PAC, (StreamPos(PAC) + SeekSize)) ' Von da an bis zum Dateianfang der gesuchten Datei springen.

Local ReturnMe:TBank = CreateBank(SearchFileSize)

ReadBank(ReturnMe, PAC, 0, SearchFileSize)

Return ReturnMe
Else
Print("PACERR: Unexpected End-of-File")
Return Null
EndIf
Else
Return Null
EndIf
End Function
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group