To write and read any binary data, you only need to use the functions provided for this purpose:
. For these functions, spaces and newlines are just bytes like any others. Depending on the application,
etc. may also be useful.
To know where data can be found in the file, you need to know the file structure. Then you can navigate to the required position in a suitable manner. Here is a practical example from the first lines of my ID3 parser up to the point where the ID3 tag begins:
Code: Select all
Function p_ReadID3Frames(f$)
p_DisableLineHook()
Local ID3Debug=False
Local title$, interpr$, year$, picturedata$, picturelist = "", "", "", "", {}
Local album$=""
Local id3version="-"
If ID3Debug Then DebugPrint(f$)
Local fsize=FileSize(f$)
If fsize<16 ; (willkürlich gewählt)
p_PrintMessage(True, 10000,p_GetCatalogString(40, "beschädigte Datei "),f$,p_GetCatalogString(41, " Größe"),fsize)
Return(False, interpr$, title$, year$, {})
EndIf
Local err= ?OpenFile(1, f$, #MODE_READ)
If err<>#ERR_NONE
p_PrintMessage(True, 40000,p_GetCatalogString(42, "Lesen der ID3-Tags: Die Datei"),f$, p_GetCatalogString(43, "kann nicht gelesen werden: "),GetErrorName(err))
Return(False, interpr$, title$, year$, {})
EndIf
; ggf. vorhandene Nullen am Dateianfang überspringen
; (ursprünglich nur die zweite Schleife, aber bei sehr vielen Nullen war das zu langsam)
Local i=0
Local fsizek=fsize-4
While ReadInt(1) = 0
i=i+4
If i >= fsizek
p_PrintMessage(True, 90000,p_GetCatalogString(44, "beschädigte Datei "),f$)
Return(False, interpr$, title$, year$, {}) ; Abbruch, weil Datei nur Nullen enthält
EndIf
Wend
Seek(1, -4, #SEEK_CURRENT) ; vier Byte zurück
i=FilePos(1)
Local fsizek=fsize-1
While ByteAsc(ReadBytes(1, 1),0) = 0
; eigentlich "If FilePos(1) >= FileSize(f$)-1" , aber etwas beschleunigt
i=i+1
If i >= fsizek
p_PrintMessage(True, 90000,p_GetCatalogString(44, "beschädigte Datei "),f$)
Return(False, interpr$, title$, year$, {}) ; Abbruch, weil Datei nur Nullen enthält
EndIf
Wend
Seek(1, -1, #SEEK_CURRENT) ; ein Byte zurück
Local GarbageAtBegin=0
If FilePos(1)>0
GarbageAtBegin=FilePos(1)
If ID3Debug
DebugPrint(FilePos(1),"Null-Bytes am Dateianfang übersprungen.")
DebugPrint("Erstes Byte",HexStr(ByteAsc(ReadBytes(1, 1))))
Seek(1, -1, #SEEK_CURRENT)
EndIf
EndIf
If ID3Debug
; die ersten 50 Bytes auf die Debugkonsole
gTagbuffer$=ReadBytes(1, 50)
p_PrintHex(MidStr(gTagbuffer$,0,50,#ENCODING_RAW))
Seek(1, -50, #SEEK_CURRENT)
gTagbuffer$=Nil
EndIf
/*
Der ID3v2-Tag-Header besteht aus 10 Bytes:
ID3v2/Datei-Bezeichner "ID3"
ID3v2-Version $03 00
ID3v2-Flags %abc00000
ID3v2-Größe 4 * %0xxxxxxx
*/
If ReadBytes(1, 3) = "ID3"
; wenn die (von Null verschiedenen) Daten mit ID3 beginnen, sollte das ein
; Tag-Header sein, und es sollte ID3-v2-Frames geben
; restlicher Header
header=ReadBytes(1, 3) ; Version, Flags
id3version="2."..ByteAsc(header,0).."."..ByteAsc(header,1)
If ID3Debug Then DebugPrint("ID3v"..id3version)
If gRndmzFramesReadFinished Then p_PrintMessage(False, 9000,p_GetCatalogString(45, "Tagversion ID3v")..id3version)
;DebugPrint("Flags",BinStr(ByteAsc(header,2), #BYTE))