Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Datei von Datei exportieren? (https://www.delphipraxis.net/31345-datei-von-datei-exportieren.html)

Luckie 9. Okt 2004 10:16

Re: Datei von Datei exportieren?
 
Zitat:

Zitat von Newbie44
ja, du hast recht es ist ein offset, aber die zahlen sind vertauscht, wenn man die z. B. B5E86401 ---> 0164E8B5

Da ist nichts vertauscht. Es dürfte sich nur um, ja wie war das noch mal, Intel benutzt das Little Endian Format und MAC zum Beispiel das Big Endian oder war es umgekehrt? Jedenfalls unterscheiden sich beide Formate dahingehen, dass die Werte im Speicher anders abgelegt werden.

Zitat:

Jetzt seit ihr gefragt, wie formuliere ich das ganze in delphi?
Warum wir? Du willst doch ein Programm schreiben, welches die Dateien extrahiert, nicht wir. :roll:

Newbie44 9. Okt 2004 10:22

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:

Newbie44 9. Okt 2004 10:25

Re: Datei von Datei exportieren?
 
Jo, es ist die selbe distanz, immer 21 Zeichen bis zum nächsten offset

sebby :thumb:

Luckie 12. Okt 2004 02:20

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:
{************************************************************

  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.

************************************************************}
Die interessaneten Routinen schon mal hier im Posting:

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.
Seite 3 von 3     123   

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