![]() |
Binärdatei Record auslesen\zuweisen
Der record..
Delphi-Quellcode:
Wenn ich die Datei öffne dann ist FileSize = Buffersize, die Bytes die gelesen wurden sind genauso groß.
TSTChannel = record
ID : Integer; streamName : Array [0..250] of AnsiChar; freq : single; volume : single; pan : single; mute : byte; solo : byte; duration : Integer; percent : Integer; grouplevel : single; led : byte; rMeterValue : single; reserved : Array [0..25] of AnsiChar; end; Aber irgendwie bekomme ich nicht die werte die eigentlich zurück geliefert werden müssten. Wenn ich das Array des streamName vergrößere funktioniert so gut wie gar nicht. warum hat das so einen Einfluss? Eigentlich dürfte es doch egal sein wie groß der Speicher für den Namen zugewiesen wird.
Delphi-Quellcode:
streamName : Array [0..MASX_PATH] of AnsiChar;
Wieder so ein Mysterium für mich. gruss |
AW: Binärdatei Record auslesen\zuweisen
Wo kommt die Datei denn her? Schreibst Du die selbst? Hilft es evtl., den Record als packed zu deklarieren?
|
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Ich kenne nur die Definition. Und öffne sie so.
Delphi-Quellcode:
var
Channel: array[1..MAXCHANNEL] of TSTChannel;
Delphi-Quellcode:
Der wert im Channel[1].Volume müsste 50 sein ist er aber nicht.
fHandle := CreateFile(PWideChar(sFile), GENERIC_READ, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (fHandle <> INVALID_HANDLE_VALUE) then begin FillChar(Channel, sizeof(TSTChannel) * MAXCHANNEL, 0); BufferSize := sizeof(TSTChannel) * MAXCHANNEL; FileSize := GetFileSize(fHandle, @FileSize); if (FileSize = INVALID_HANDLE_VALUE) then FileSize := 0; if (FileSize div sizeof(TSTChannel) = 8) then BufferSize := FileSize; if (FileSize < BufferSize) then BufferSize := 0 else bErrorFlag := ReadFile(fHandle, Channel[1], BufferSize, dwBytesReaden, nil); CloseHandle(fHandle); end; gruss |
AW: Binärdatei Record auslesen\zuweisen
Zeig mal etwas Code. Bin mir nicht ganz sicher wo dein Problem liegt.
Wenn du das streamName-Array vergrößert rutschen alle anderen Felder im Array entsprechend viele Bytes nach hinten und nichts ist mehr am richtigen Ort. Woher hast du denn die Record-Definition von TSTChannel? Du hast gesagt du schreibst das Record noch nicht. Wer schreibt es denn und bist du dir sicher, dass deine Record-Definition richtig ist? |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
EDIT: Zitat:
Aber wie gesagt kommen falsche werte an. Wenn ich packed nehme dann ist der Buffersize und Bytesread kleiner wie Filesize. gruss |
AW: Binärdatei Record auslesen\zuweisen
Die Felder des Records liegen im Speicher hintereinander. Wenn Du eines der vorderen Felder - z.B. streamName - vergrößerst, rutscht alles Folgende nach hinten. Das ist schon plausibel.
Die Felder des Array können, müssen aber nicht zwingend /direkt/ hintereinander liegen. Das kannst Du mit dem Thema "Alignment" steuern. Oder eben mit dem Schlüsselwort "packed", dann liegt das Zeugs wirklich dicht an dicht im Speicher. Entscheidend aber ist, dass Du dasselbe Alignment verwendest wie die Software, die die Datei schreibt. Da es letztlich nur 1, 2, 4, und 8 als gängige Möglichkeiten gibt, ist ausprobieren ggf. die schnellste Lösung. |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Hmm.. kann jetzt aber auch nicht sehen was falsch sein könnte. Die Datei ist von fly-worship 3KB Danke. gruss |
AW: Binärdatei Record auslesen\zuweisen
Ist nicht das eigentliche Problem, aber
Delphi-Quellcode:
solltest du zu
OPEN_ALWAYS
Delphi-Quellcode:
ändern (bei
OPEN_EXISTING
![]() ![]()
Delphi-Quellcode:
auf
INVALID_HANDLE_VALUE
Delphi-Quellcode:
prüfen (ist der selbe Wert, nur nicht so verwirrend beim lesen :P). Den zweiten Parameter kannst du hier auch auf
INVALID_FILE_SIZE
Delphi-Quellcode:
setzen statt
nil
Delphi-Quellcode:
(den Wert überschreibst du ja eh wieder sobald das Resultat der Funktion zugewiesen wird).
@FileSize
Zitat:
Delphi-Quellcode:
, also
{$A1}
Delphi-Quellcode:
?
packed
Edit: Kannst du mal die originale (unveränderte) Definition von
Delphi-Quellcode:
verlinken?
TSTChannel
|
AW: Binärdatei Record auslesen\zuweisen
Zitat:
glaube das hatten wir schon mal. Das andere werde ich ändern Danke.
Code:
EDIT:
TYPE STChannel
ID AS LONG streamName AS ASCIIZ * %MAX_PATH freq AS SINGLE volume AS SINGLE pan AS SINGLE mute AS BYTE solo AS BYTE duration AS LONG percent AS LONG grouplevel AS SINGLE led AS BYTE rMeterValue AS SINGLE reserved AS ASCIIZ * 25 '// Total 320 bytes. END TYPE Geänderte Teil
Delphi-Quellcode:
Hab zwei shots angehängt.
fHandle := CreateFile(PWideChar(sFile), GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (fHandle <> INVALID_HANDLE_VALUE) then begin FillChar(Channel, sizeof(TSTChannel) * MAXCHANNEL, 0); BufferSize := sizeof(TSTChannel) * MAXCHANNEL; FileSize := GetFileSize(fHandle, nil); if (FileSize = INVALID_FILE_SIZE) then FileSize := 0; if (FileSize div sizeof(TSTChannel) = 8) then BufferSize := FileSize; if (FileSize < BufferSize) then BufferSize := 0 else bErrorFlag := ReadFile(fHandle, Channel[1], BufferSize, dwBytesReaden, nil); CloseHandle(fHandle); end; Bei Packed ist der ganze Speicher verschoben. gruss |
AW: Binärdatei Record auslesen\zuweisen
PS: das "gute" alte
Delphi-Quellcode:
funktioniert immernoch.
file of TMyRecord
Externe Records NIEMALS pur definiert, sondern ausschließlich PACKED oder mit explizitem
Delphi-Quellcode:
(direkt davor oder über die ganze Datei)
{$ALIGN x}
und
Delphi-Quellcode:
, egal ob Datei, Stream oder sonstwas.
{$ALIGN 1} = PACKED
denn du willst ja nicht, dass sich die Ausrichtugn irgendwann mal ändert und es dann nicht mehr zu deiner Datei passt. Extern = von/nach außerhalb deines Programms. (mit der Ausnahme, dass wenn die Datei/Stream ausschließlich nur von der eigenen EXE geschrieben/gelesen wird und das nicht über Programminstanzen hinweg) AnsiChar war schonmal gut (kann auch für UTF-8 genutzt werden) oder eben WideChar, wegen Unicode. Denn dynamische/compilerabhängige Typen sind auch verboten. |
AW: Binärdatei Record auslesen\zuweisen
Sieht hier aber so aus, als ob das standard Alignment (von 4?) korrekt wäre. Die Pfade der hinteren Einträge des Arrays stimmen ja bis aufs letzte Byte exakt. Sicher, dass
Delphi-Quellcode:
an der Stelle 50 sein muss?
volume
|
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Es war mal vor Jahren 4 und in etwas aktuelleren Delphis ist es 8 (für Windows ... in anderen OS vielleicht anders) ![]() PS: ![]() ![]() ALIGN gibt aber nur die "maximale" Ausrichtung an. Kleiner Typen werden an ihrer Größe ausgerichtet. > WORD alle 2 Byte (außer &Align ist unter 2) > Interger alle 4 Byte, also nach einem WORD bliebe eine Lücke von 2 |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Zitat:
Habe alles versucht.
Delphi-Quellcode:
{$Align On}
{$ALIGN 8} TSTChannel = record ID : Integer; streamName : Array [0..250] of AnsiChar; freq : single; volume : single; pan : single; mute : byte; solo : byte; duration : Integer; percent : Integer; grouplevel : single; led : byte; rMeterValue : single; reserved : Array [0..25] of AnsiChar; end; {$Align Off}
Delphi-Quellcode:
Array [0..250] of AnsiChar;
Auf
Delphi-Quellcode:
Array [0..MAX_PATH] of AnsiChar;
dann kracht es. gruss |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
![]()
Delphi-Quellcode:
var F: file of TSTChannel;
Zitat:
Delphi-Quellcode:
{$A+} = {$ALIGN ON} = {$ALIGN 8} wobei 8 der DEFAULT ist
{$A-} = {$ALIGN OFF} = {$ALIGN 1}
Delphi-Quellcode:
{$ALIGN 8} // ab hier 8
TSTChannel = record .. end; {$ALIGN ON} // ab hier wieder DEFAULT |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Aber ich benötige ein Array. gruss |
AW: Binärdatei Record auslesen\zuweisen
Das ist ein Array bzw. eine Liste. :zwinker:
FileSize = Anzahl der Records, also in der API für diese "Typed Files" FilePos = Index des Record FileSize und FilePos werden intern auf RecSize umgerechnet. ![]()
Delphi-Quellcode:
=
file of AnsiChar
Delphi-Quellcode:
= eine Textdatei
Text
|
AW: Binärdatei Record auslesen\zuweisen
Du meinst wenn ich dich richtig verstehe anstelle von CreateFile..
Nur das löst mein Problem nicht. Letztendlich ein Ersatz für die WinApi32. gruss |
AW: Binärdatei Record auslesen\zuweisen
Drum hatte ich es eigentlich auch nur nebenbei erwähnt.
Aber ansonsten wurde auch schon alles Wichtige genannt. * die Speicherausrichtung * die Art der Typen (z.B. AnsiChar und WideChar, aber nicht Char) Arrays werden wie ihr enthaltener Typ ausgerichtet, außer bei "packed array", und bei Records wie ihr größter Typ, außer bei "packed record". |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Das ist wieder ein fall wo ich mir nur selber helfen kann.. Also nochmal Danke an alle die versucht haben für mich mitzudenken. :) gruss |
AW: Binärdatei Record auslesen\zuweisen
So, noch mal kurz vor Feierabend ins Forum geschaut.
Dein Record hat 312 Byte. Die Blöcke in der Datei sind 320 Byte groß. Wenn ich das richtig in Erinnerung habe, sind Records standardmäßig nicht gepackt. In Turbo-Pascal war das noch anders. :) Entweder ist dein Record falsch definiert oder die Speicher-Ausrichtung passt nicht. Ich habe das nicht exakt nachgerechnet, aber ich meine, dass die Ausrichtung zu einer Verschiebung um 10 Byte führen sollte. Das passt dann immer noch nicht zu den 320 Byte. Lies das doch mal in Blockgrößen (Record of Array [0..319] definieren) zu 320 Byte ein und teste Stückweise, wie es in den geplanten Record passt. Klassisches Beispiel für einen varianten Record. |
AW: Binärdatei Record auslesen\zuweisen
Liste der Anhänge anzeigen (Anzahl: 1)
Hab arge Probleme mit deiner RecordSize, schreib oder Knipps mal erstes Record und sag exakt wie dafür die werte sein müßten.
Momentan komm ich damit nicht klar, siehe Bild. |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Standardmäßig ist jede Variable im Arbeitsspeicher ausgerichtet, für einen "optimalen" Speicherzugriff, ohne rumschieben und kopieren zu müssen. PS: wie wäre es mit einer Embedded DB? (Firebird, SQLite, ...) |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Wenn es das ist was du meinst. Der Streamname passt ja ist bei mir auch so. ;) gruss |
AW: Binärdatei Record auslesen\zuweisen
Sry himitsu, du hast natürlich Recht. Bin im Moment mit dem Handy angemeldet. Ich korrigiere das, sobald ich kann
|
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Alternativ spiel mit diesem Schnippsel rum, mit dem entstand das Bild von oben. Nicht lachen aber so mach ich es.
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
type TSTChannel = packed record ID : Integer; // streamName : Array [0..250] of AnsiChar; streamName : Array [0..MAX_PATH] of AnsiChar; freq : single; volume : single; pan : single; mute : byte; solo : byte; duration : Integer; percent : Integer; grouplevel : single; led : byte; rMeterValue : single; reserved : Array [0..25] of AnsiChar; end; var STChannel : TSTChannel; MyRead: File of TSTChannel; i : Integer; begin Memo1.Clear; AssignFile(MyRead, '.\Channels.bin'); Reset(MyRead); try while not EOF(MyRead) do begin Read(MyRead, STChannel); with STChannel do begin Memo1.Lines.Add('ID: '+IntToStr(ID)); Memo1.Lines.Add('StreamName: '+String(StreamName)); Memo1.Lines.Add('Freq: '+FloatToStr(freq)); Memo1.Lines.Add('Volume: '+FloatToStr(Volume)); Memo1.Lines.Add('Pan: '+FloatToStr(Pan)); Memo1.Lines.Add('Mute: '+IntToStr(Mute)); Memo1.Lines.Add('Solo: '+IntToStr(Solo)); Memo1.Lines.Add('Duration: '+IntToStr(Duration)); Memo1.Lines.Add('Percent: '+IntToStr(Percent)); Memo1.Lines.Add('GroupLevel: '+FloatToStr(GroupLevel)); Memo1.Lines.Add('Led: '+IntToStr(Led)); Memo1.Lines.Add('rMeterValue: '+FloatToStr(rMeterValue)); Memo1.Lines.Add('Reserved: '+String(Reserved)); Memo1.Lines.Add(''); end; end; finally CloseFile(MyRead); end; end; |
AW: Binärdatei Record auslesen\zuweisen
Ich habe nur das Bin file und versuche daraus die Korrekten Daten einzulesen.
Da mein einlesen der Datei fehlschlägt kann ich dir auch keine korrekten Daten für den erste Record liefern. Zitat:
gruss |
AW: Binärdatei Record auslesen\zuweisen
Hmm..
Ich werfe einfach mal Big-Endian/Little-Endian in den Raum. Eventuell wird für die Kodierung des Single-Wertes im Ausgangssystem auch was ganz anderes verwendet... (Nur so eine Idee ;) ) |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Packed funktioniert nicht den dann verschiebst du den gesamten Speicher des Rekords. Sieh Anhang. gruss |
AW: Binärdatei Record auslesen\zuweisen
Falls du (ungefähr) weißt was in einem dieser Channel Records drin stehen müsste, dann öffne die .bin doch mal in einem Hex-Editor und dann siehst du wie lang das Record ist und wie die Felder liegen. Dementsprechend kannst du dann deinen Code anpassen. Oder falls die Datei nicht so groß ist usw. kannst du sie vllt. ja mal hochladen.
|
AW: Binärdatei Record auslesen\zuweisen
Zitat:
2,81 KB (2.880 Bytes)... gruss |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Ich hab gefragt ob du die Datei mal hochladen könntest, damit wir uns das mal anschauen können. |
AW: Binärdatei Record auslesen\zuweisen
Hmm..
Wenn ich dass richtig sehe, sind die Array Definitionen falsch! Richtig müsste es so sein: (Oben das Original)
Delphi-Quellcode:
So kommt auch die Länge von 320 Bytes hin...
{
MAX_PATH = 260; TYPE STChannel ID AS LONG streamName AS ASCIIZ * %MAX_PATH freq AS SINGLE volume AS SINGLE pan AS SINGLE mute AS BYTE solo AS BYTE duration AS LONG percent AS LONG grouplevel AS SINGLE led AS BYTE rMeterValue AS SINGLE reserved AS ASCIIZ * 25 '// Total 320 bytes. END TYPE } type TSTChannel = packed record ID : LONGINT; streamName : Array [0..MAX_PATH-1] of AnsiChar; freq : single; volume : single; pan : single; mute : BYTE; solo : BYTE; duration : LONGINT; percent : LONGINT; grouplevel : single; led : BYTE; rMeterValue : single; reserved : Array [0..24] of AnsiChar; end; Ein C-Array von 25er Länge ist in Delphi ein Array von 0..24 ! (Erstellt mit D6) |
AW: Binärdatei Record auslesen\zuweisen
Du hast Recht. Doof, dass echt keiner von uns in den ganzen 4 Seiten drauf gekommen ist :oops: :lol:
Die Arrays waren jeweils 1 Element zu lang. |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
![]() gruss |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
@HolgerX Danke vielmals.. gruss |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Per HexEdit zeigt der mir für #8 auch einen gekappten Namen an ("weetly Broken (A)\Loop.mp3" alle anderen beginnen mit "Sweetly Broken") und #9 ist leer. Könnte es sein dass das (#8 und #9) entfernte Records sind? Also Überbleibsel. |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
gruss |
AW: Binärdatei Record auslesen\zuweisen
Liste der Anhänge anzeigen (Anzahl: 1)
Hmm..
Hab mal nen kleines Testtool... Scheint alles nun zu passen.. (Erstellt mit D6) |
AW: Binärdatei Record auslesen\zuweisen
Ok, Dein Tool bringt die gleichen Ergebnisse, #8 und #9 entweder defekt oder sonst was.
Delphi-Quellcode:
Danke für check!
procedure TForm2.Button1Click(Sender: TObject);
type TSTChannel = packed record ID : LONGINT; streamName : Array [0..MAX_PATH-1] of AnsiChar; freq : single; volume : single; pan : single; mute : BYTE; solo : BYTE; duration : LONGINT; percent : LONGINT; grouplevel : single; led : BYTE; rMeterValue : single; reserved : Array [0..24] of AnsiChar; end; var STChannel : TSTChannel; MyRead: File of TSTChannel; begin Memo1.Clear; AssignFile(MyRead, '.\Channels.bin'); Reset(MyRead); try while not EOF(MyRead) do begin Read(MyRead, STChannel); with STChannel do begin Memo1.Lines.Add('RECORD >>> '+IntToStr(FilePos(MyRead))); // Da ID nichts liefert, liefer ich mir selbst was Memo1.Lines.Add('ID: '+IntToStr(ID)); Memo1.Lines.Add('StreamName: '+String(StreamName)); Memo1.Lines.Add('Freq: '+FloatToStr(freq)); Memo1.Lines.Add('Volume: '+FloatToStr(Volume)); Memo1.Lines.Add('Pan: '+FloatToStr(Pan)); Memo1.Lines.Add('Mute: '+IntToStr(Mute)); Memo1.Lines.Add('Solo: '+IntToStr(Solo)); Memo1.Lines.Add('Duration: '+IntToStr(Duration)); Memo1.Lines.Add('Percent: '+IntToStr(Percent)); Memo1.Lines.Add('GroupLevel: '+FloatToStr(GroupLevel)); Memo1.Lines.Add('Led: '+IntToStr(Led)); Memo1.Lines.Add('rMeterValue: '+FloatToStr(rMeterValue)); Memo1.Lines.Add('Reserved: '+String(Reserved)); Memo1.Lines.Add(''); end; end; finally CloseFile(MyRead); end; end; |
AW: Binärdatei Record auslesen\zuweisen
Zitat:
Zitat:
Das Teil ist nur zum testen meiner LIB. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz