![]() |
Streams: existierende Daten entfernen / einfügen
Ich hantiere gerade bei Streams herum.
Nun tauchen bei mir folgende Probleme auf:
mfg mytar [edit=sakura] [Klammern entfernt] Mfg, sakura[/edit] |
Re: [Streams]: existierende Daten entfernen / einfügen
Kann mir hier niemand weiterhelfen?
Hier nochmals: Ich hab eine Datei, und öffne sie via Stream, nun möchte ich mit Seek() die entsprechende Position suchen, und dann was in den Stream einfügen, oder herauslöschen. Die Datei hab ich zuvor selbst erzeugt, ich kenne also die Dateistruktur. mytar |
Re: [Streams]: existierende Daten entfernen / einfügen
Wenn du mitten reinschreiben willst, dann wird dir nichts anderes übrigbleiben, als ab der Stelle den Rest in einem memoryStream zwischenzuspeichern, deinen Datensatz reinschreiben und dann den gesicherten Rest wieder dranzuhängen.
|
Re: [Streams]: existierende Daten entfernen / einfügen
Danke! Eine gute Lösung, ich bin natürlich nicht draufgekommen!
mytar |
Re: [Streams]: existierende Daten entfernen / einfügen
Aber wenn ich nach der Position suche und der Stream 4 MB groß ist, dauert das bei mir schon länger, ich glaube ich mach es nicht richtig:
Ich möchte ein Prog schreiben, was ein Bild und text in eine Datei speichert, erst soll es ein paar Memolines in den TFileStream schreiben und dann das Bild. Da der Text des Memos keine Begrenzung haben soll, würde ich beim Datei schreiben einfach ein '[END]' in den Stream schreiben. Suchen würde ich das Ende des Memos/den Anfang des Bildes mit der folgenden Funktion (hab ich mir ausgedacht, aber sie ist so langsam. Wie sucht man nach einem "Wort" in einem Stream ("professionell")?)
Delphi-Quellcode:
Also nochmal meine frage: Wie sucht man nach einer Zeichenfolge in einem Stream?
//Aufruf
Position := GetOffsetOf(FS, '[END]')-1; FS.Position //Funktion function GetOffsetOf(FS: TFileStream; S: String): Integer; var C: Char; B, I: integer; begin I := 0; Result := 0; While I < FS.Size-1 do begin FS.ReadBuffer(C, SizeOf(C)); Inc(I); if UpCase(C) = UpCase(S[1]) then begin Result := I; for B := 2 to Length(S) do begin FS.ReadBuffer(C, SizeOf(C)); Inc(I); if UpCase(C) <> UpCase(S[B]) then begin Result := 0; Break; end; if B = Length(S) then Exit; end; end; end; end; Danke schonmal! |
Re: [Streams]: existierende Daten entfernen / einfügen
Zitat:
Delphi-Quellcode:
Prinzip: Auf gut Glück einfach nen Block einlesen, und vergleichen. Wenn's nicht passt, dann Blockgröße-1 zurückspringen, und nochmals lesen... usw.usf.
var
str: string[5]; . . . Stream.Read(str, 5); while str <> 'hallo' do Stream.Seek(-4, soFromCurrent); Stream.Read(str, 5); end; Ist evtl. nicht so performant, aber anders hab ich das bisher auch noch nicht gemacht ;) gruss, dizzy |
Re: [Streams]: existierende Daten entfernen / einfügen
Das ist ja schonmal ein Anfang.
Mir ist gerade was aufgefallen: Wenn ich jedes Zeichen einzeln schreibe (von 'Hallo') wird die Datei 5 Bytes groß und es steht richtig "Hallo" drin (wenn man sie mit HexEditor öffnet). Mach ich es mit
Delphi-Quellcode:
Dann ist die Datei nurnoch 4 Bytes groß :gruebel: und mit HE kann man Hallo nicht lesen.
S := 'Hallo';
WriteBuffer(S, SizeOf(S)); Ich habs aber noch nicht geschafft das wieder richtig herzustellen, darum meine (2.) Frage: Für das Beispiel "Hallo" -> Wie schreibt und ließt man richtig in und aus Streams? :pale: [Edit]@dizzy: Wieso um 4 zurück? Da könntest du doch was verpassen, einmal liest du bsw. 'lo...' und nach dem zurückspringen '..Hal'!? (Wenn ich das richtig sehe).[/Edit] |
Re: [Streams]: existierende Daten entfernen / einfügen
Moin!
S ist ein AnsiString und daher nur ein Zeiger auf den String. Daher ergibt SizeOf() auch eine 4, weil es ein Pointer ist. Somit folgendes: 1. Nutze anstatt SizeOf() die Funktion Length() um die Länge des Strings zu ermitteln. 2. Gebe der Schreibroutine das erste Zeichen an.
Delphi-Quellcode:
MfG
S := 'Hallo';
WriteBuffer(S[1], Length(S)); Muetze1 |
Re: [Streams]: existierende Daten entfernen / einfügen
:thumb: Das funktioniert! :thumb:
:idea: Stelle fest: Auslesen funktioniert dann folgender Maßen
Delphi-Quellcode:
const
L: Integer = 5; //Länge var S: Array[0..MAX_PATH-1] of Char; //oder S: Array[0..L-1] of Char; FS: TFileStream; { ... } FS.ReadBuffer(S, L); Soweit hätten wirs damit schonmal :!: |
Re: [Streams]: existierende Daten entfernen / einfügen
Da gibt's doch noch was besseres (meine Methode geht zwar auch, aber das hab ich in nem Tut gelesen):
Delphi-Quellcode:
:dancer2: Soviel dazu!
var
S: String; begin { ... } SetLength(S, Len); FS.ReadBuffer(S[1], Len); { ... } end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 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