![]() |
Datei teilweise kopieren
Hallo,
ich habe ein Problem für das ich bislang keine Lösung habe finden können: Ich möchte aus einer Quelldatei byteweise Daten in eine Zieldatei kopieren. Allerdings möchte ich nicht die gesamte Datei kopieren, sondern nur bestimmte Teile. Hierzu habe ich im Vorhinein die Datei durchsucht und die Anfangspositionen und Längen der Teile ermittelt, die nicht kopiert werden sollen. Der Benutzer soll zusätzlich noch auswählen können, welche Daten nicht mit übernommen werden sollen. Ich hatte schon die Idee über einen Zähler die Position mit aufzuzeichnen und die Sache etwa so zu lösen:
Delphi-Quellcode:
Das dumme ist nur, dass bei den Case oder X in [Y..Z] Abfragen keine Variablen zulässig sind, was diesen Versuch nicht glücken lässt.
Byte:=0;
While Not EOF(FromFile) Do Begin Read(FromFile,Byte); Case P Of Start1..Ende1 : If Not CheckBox1.Checked Then Write(ToFile,Byte); Start2..Ende2 : If Not CheckBox2.Checked Then Write(ToFile,Byte); Start3..Ende3 : If Not CheckBox3.Checked Then Write(ToFile,Byte); . . // Wenn nicht zum löschen ausgewählt, . // nur dann kopieren! End; Inc(P); End; Hat jemand eine Idee? Ich schätze, dass es hierfür sogar schon eine Lösung im Forum gibt und ich mich nur zu dumm angestellt habe, sie zu finden. |
Re: Datei teilweise kopieren
Delphi-Quellcode:
Eventuell so?
Byte:=0;
While Not EOF(FromFile) Do Begin Read(FromFile,Byte); if ((P >= Start1) and (P <= Ende1) and not CheckBox1.Checked) or (P >= Start2) and (P <= Ende2) and not CheckBox2.Checked) or (P >= Start3) and (P <= Ende3) and not CheckBox3.Checked) or ...) then Write(ToFile,Byte); Inc(P); End; |
Re: Datei teilweise kopieren
Danke für die schnelle Antwort.
Im Prinzip funktioniert das ganze exakt so, wie es meinem Quellcodevorschlag zu entnehmen war. Nur habe ich dort leider was entscheidendes vergessen: Es soll nämlich immer dann, wenn die Position nicht in die fraglichen Bereiche fällt, kopiert werden. Bei der Case Anweisung fehlt daher am Ende noch ein Else Write(ToFile,Byte);. Im Moment ist es leider so, dass von den ausgewählten Bereichen die gewünschten kopiert und die unerwünschten weggelassen werden. Das hat mich schonmal ein Stück weiter gebracht, weil ich so feststellen konnte, das meine Endwerte (EndeX) nicht exakt waren. Allerdings wird alles andere auch nicht kopiert. Ich hatte schon an verschachtelte If Schleifen gedacht aber schnell festgestellt, dass er die übrigen 2 Bereiche nicht mehr prüft, wenn der Wert nicht mehr unter die erste Bedingung fällt. |
Re: Datei teilweise kopieren
Ich habe jetzt die (bzw. eine mögliche) Lösung gefunden. Ich muss mich insoweit korrigieren, als es doch mit verschachtelten If Schleifen funktioniert. Für den Fall, dass jemand Interesse haben sollte, habe ich den Quelltext der Lösung gleich noch mal beigefügt.
Jetzt wüsste ich nur gern noch, ob jemand eine Idee hat, wie man das ganze schneller machen könnte und ob man das Begin und End weglassen kann, in die ich jeweils die Abfrage If Not IDv?.Checked Then Write(TF,BDummy); eingefasst habe. Hier der Quelltext:
Delphi-Quellcode:
P:=0;
While Not EOF(FF) Do Begin Read(FF,BDummy); If (P>=V1Pos) And (P<=V1Size) Then Begin If Not IDv1.Checked Then Write(TF,BDummy); End Else Begin If (P>=V2Pos) And (P<=V2Size) Then Begin If Not IDv2.Checked Then Write(TF,BDummy); End Else Begin If (P>=VLPos) And (P<=VLSize) Then Begin If Not IDvL.Checked Then Write(TF,BDummy); End Else Begin If (P>=VAPos) And (P<=VASize) Then Begin If Not IDvA.Checked Then Write(TF,BDummy); End Else Write(TF,BDummy); End; End; End; End; |
Re: Datei teilweise kopieren
Wenn ich die Bereitstellung der nicht zu kopierenden Bereiche außen vor lasse (weil eine Frage der Benutzerschnittstelle), dann könnte ich mir die Erzeugung der Ausgabedatei auch so vorstellen:
Delphi-Quellcode:
Die auszulassenden Bereiche werden im DropArray übermittelt und die Dateien werden über FileStreams angesprochen. Safety code ist nicht an Bord.
type
TDropOut = record Start: cardinal; Size: cardinal; end; TDropArray = array of TDropOut; procedure DropCopy(fsSource, fsTarget: TStream; drops: TDropArray); var i: integer; begin fsSource.Position := 0; fsTarget.Position := 0; for i := Low(drops) to High(drops) do begin fsTarget.CopyFrom(fsSource, drops[i].Start - fsSource.Position); fsSource.Seek(drops[i].Size, soFromCurrent); end; fsTarget.CopyFrom(fsSource, fsSource.Size - fsSource.Position); end; Grüße vom marabu |
Re: Datei teilweise kopieren
@marabu: Danke für den Tip. Ich verstehe den Vorschlag aber so, dass ich mit Streams arbeiten muss. Das habe ich aber noch nie getan und habe dementsprechend wenig Ahnung davon. Falls ich mein Programm nochmal überarbeite, werde ich es aber mal versuchen.
Ansonsten habe ich hier einen ![]() Falls jemand das ganze verbessern will, stelle ich den Quelltext, unter der Bedingung, dass das Endergebnis Freeware bleibt, gern zur Verfügung. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:40 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