![]() |
Re: Datei von Datei exportieren?
Zitat:
Zitat:
|
Re: Datei von Datei exportieren?
:cry: :cry: :cry: :cry: :cry:
Schade, ich habe sowas noch nie gemacht. Aber wenn ich das ganze mit 2 Filestreams machen würde, könnte es klappen, nur ich sehe ein problem, mit dem länge der datei, und zwar, müsste die datei ja nur bis zum nächsten offset gehen, mal gucken, vielleicht ist die selbe distanz zum nächsten offset sebby :roll: |
Re: Datei von Datei exportieren?
Jo, es ist die selbe distanz, immer 21 Zeichen bis zum nächsten offset
sebby :thumb: |
Re: Datei von Datei exportieren?
Liste der Anhänge anzeigen (Anzahl: 1)
So, voll funktionstüchtiges Demo im Anhang. Die relevanten Routinen sind wiederverwendbar und es wird nur demonstriert, wie man sie einsetzt. Erklärungen befinden sich im Quellcode, die hardgecodeten Stellen sind markiert.
Delphi-Quellcode:
Die interessaneten Routinen schon mal hier im Posting:
{************************************************************
Demoprogramm für die Funktionen zum Einlesen der Indexdatei und zum extrahieren einer Dstei aus der Quelldatei. Anmerkungen: ============ Die Funktion ReadIndexFile liest die Indexdatei aus und gibt ein Array vom Typ TFileInfos zurück. TFileInfos ist ein dynamisches Array vom Typ TIdxFile. Die Prozedur ExtractFile extrahiert aus einer beliebigen Quelldatei eine Byte-Sequenz und schreibt sie in die angegebene Datei. Der Typ der Quelldatei ist beliebig. Die TODO's markieren die Stellen im Demoprogramm, die hardgecodet sind. Wie man sieht befinden sie sich nur in den Stellen im Quellcode, wo die Funktionsweise der relevanten Routinen demonstriert werden. Die relevanten Routinen sind also wiederverwendbar. Willst du nun alle Dateien extrahieren, liest du die Indexdatei ein, gehst sie in einer Schleife durch und rufst die Prozedur ExtravtFile mit den entsprechenden Parametern auf. Aufpassen musst du nur bei der letzten Datei, da es dort keinen Nachfolger gibt: IdxFile := FileInfoArray[IDX]; IdxFileNext := FileInfoArray[IDX+1]; // <-- !!! Eine Lösung wäre einen zweiten Record zu definieren, der auch die Dateigröße behinhaltet und dessen Feld für die Dateigröße gleich so mit der Dateigröße zu füllen, wie es beim Anzeigen der Indexdatei im Listview gemacht wird: NewItem.SubItems.Add(IntToStr(FileInfoArray[i + 1].OffSet - FileInfoArray[i].OffSet)); Schlussbemerkung: ================= @Newbie44: Ich bin der Meinung dass es sauber programmiert ist. Du kannst dir ja mal im Quellcode ankucken, wie man Fehler behandelt und sauber abfängt. Wie du siehst, haben sie einen relativ hohen Anteil am Quellcode, aber das ist nötig, um eben alle auftretenden Fehler abfangen zu können. Es gibt nichts unschöneres, als einen Programm- absturz, weil eine Datei nicht geöffnet oder geschrieben werden konnte und damit muss man immer rechnen. Ich hoffe, du hast was gelernt, wenn du den Quellcode genauer studiert hast. ************************************************************}
Delphi-Quellcode:
// vermuteter Aufbau der Indexdatei:
type TIdxFile = record Filename: array[0..19] of Char; OffSet: DWord; end; PIdxFile = ^TIdxFile; TFileInfos = array of TIdxFile; // [..] //////////////////////////////////////////////////////////////////////////////// // // ExtractFile // // Extrahier eine Datei aus SrcFile nach DestFile // Wirft Exceptions EReadError bzw. EWriteError beim Lesen bzw. Schreiben // procedure ExtractFile(SrcFile, DestFile: string; Offset: Int64; FileSize: Integer); var ms: TMemoryStream; fs: TFileStream; Buffer: PByteArray; resourcestring rsEReadError = 'Fehler beim Lesen der Datei %s'; rsEWriteError = 'Fehler beim Schreiben in die Datei %s'; begin ms := TMemoryStream.Create; fs := TFileStream.Create(DestFile, fmCreate); try // Datei laden und Dateizeiger positionieren ms.LoadFromFile(SrcFile); ms.Seek(OffSet, soFromBeginning); // Speicher für Buffer anfordern GetMem(Buffer, FileSize); try try // Bytes aus SrcFile nach DestFile kopieren ms.ReadBuffer(Buffer^, FileSize); fs.WriteBuffer(Buffer^, FileSize); except on E: EReadError do raise E.Create(rsEReadError); on E: EWriteError do raise E.Create(rsEWriteError); end; finally FreeMem(Buffer, FileSize); end; finally FreeAndNil(ms); FreeAndNil(fs); end; end; //////////////////////////////////////////////////////////////////////////////// // // ReadIndexFile // // Indexdatei einlesen // Wirft eine Exception EReadError bei Lesefehler // function ReadIndexFile(Filename: string): TFileInfos; var fs: TFileStream; i: Integer; resourcestring rsEReadError = 'Fehler beim einlesen der Datei %s'; begin i := 0; fs := TFileStream.Create(Filename, fmOpenRead); try // 2 Bytes nach vorne springen, da steht noch was, aber ich weiß nicht was, // Eventuell eine Signatur oder so fs.Seek(2, soFromBeginning); // Größe des dynamisches Array setzten (Dateigröße / Recordgröße = Anzahl Datensätze) SetLength(result, fs.Size div sizeof(TIdxFile)); // so lange lesen bis wir am Ende sind while fs.Position < fs.Size do begin try fs.ReadBuffer(result[i], sizeof(TIdxFile)); Inc(i); except on E: EReadError do raise E.Create(Format(rsEReadError, [Filename])); end; end; finally FreeAndNil(fs); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:17 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