Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   File splitten (https://www.delphipraxis.net/144025-file-splitten.html)

Roookie 28. Nov 2009 01:10


File splitten
 
Hi,
ich war/bin auf der Suche nach einem Programm, mit dem man Dateien in Stücke zerteilen kann.
Aber nicht wie 1000e Programme: in eine vorgegebene Anzahl Stücke, oder in Stücke einer vorgegebenen Größe!
Ich brauche einen ganz bestimmten Abschnitt aus einer Datei, d.h. ich habe den Anfangspunkt und die Länge.
Man soll es nicht glauben, aber sowas ist nicht zu finden - es sei denn, hier kannt jemand ein Programm, daß das kann.
Also muß ich (mit meinen Anfängerkenntnissen) es mir wohl selbst programmieren.

Ein paar Code-Schnipsel (mit Streams) habe ich mal probiert, aber entweder ich oder Delphi 2.0 hat die nicht verstanden. Aber byteweises Kopieren wäre doch "tödlich".

Ich habe schonmal den Anfang gemacht: :coder:

Delphi-Quellcode:
var
  QuellFile, ZielFile : String;
  FirstByte, LastByte : LongInt;
begin
  ...
end
oder auch:

Delphi-Quellcode:
var
  QuellFile, ZielFile   : String;
  FirstByte, AnzahlBytes : LongInt;
begin
  ...
end
Für Euch ist das doch bestimmt ein Leichtes.
Aber bitte einen einfachen Code, den sogar ich verstehe.
Und bitte keine Sonder-Vorraussetzungen (wie .NET oder superneue Units oder sowas), die Delphi2/Win9x nicht kennt. Wenn ich das Programm oder den Quellcode mal veröffentliche, will ich die Benutzer nicht nötigen, irgendwelche Treiber zu installieren.
Falls das Kopieren schnell und sicher gehen würde, wäre es besonders Supa.

Vielen Dank im Voraus!

uoeb7gp 28. Nov 2009 01:32

Re: File splitten
 
Morgähn, Roookie!

Was ist die Maximalgröße der Dateien die du von bis Auslesen willst?

Wieviel Memory hast Du zur Verfügung?

Wie schnell soll das ganze Auslesen gegen (spielt Performance eine Rolle?)

Je nach dem was du an Resourcen hast, gibt es da unterschiedliche Ansätze!

lg.

Luckie 28. Nov 2009 02:07

Re: File splitten
 
Lade die Datei in einen Stream. Setzt den Dateizeiger an die gewünschte Anfangsposition und kopiere dann die Gewünschte Anzahl Bytes in einen neuen Stream. Das wäre das Prinzip.

alzaimar 28. Nov 2009 03:24

Re: File splitten
 
Geht das auch mit Delphi 2? :mrgreen:

uoeb7gp 28. Nov 2009 03:37

Re: File splitten
 
Hallo Delphianer, bei D2 ist die Streambehandlung noch sehr jungfräulich implementiert.

So sollte es dennoch ohne Probleme funktionieren.

Delphi-Quellcode:
{$R+} {$Q+} {$I+}
function ReadOffset(AStartOffset: LongWord; AEndOffset: LongWord;
  ASourceFile: PChar; ADestFile: PChar): LongBool;
var
  hSrcFile, hDestFile: LongWord;
  ptrBuffer: pointer;
  cbLen: LongWord;
  cbRead, cbWritten: LongWord;
begin
  result := false;
  ptrBuffer := nil;
  cbLen := AEndOffset - AStartOffset;
  //-- AStartOffset muss immer kleiner als AEndOffset sein
  if cbLen > 0 then begin
    //-- Existierendes File öffnen
    hSrcFile := CreateFile(ASourceFile, GENERIC_READ or GENERIC_WRITE,
      0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    //-- Wenn Ok dann weiter
    if hSrcFile <> INVALID_HANDLE_VALUE then begin
      //-- Offset ausgehend vom Anfang der Datei setzen, also beginnend von.
      if SetFilePointer(hSrcFile, AStartOffset, nil, 0) <> $FFFFFFFF then begin
        //-- Vom Heap Speicher für die zu lesende Daten anfordern
        GetMem(ptrBuffer, cbLen);
        //-- Anzahl der Bytes = AEndOffset - AStartOffset in den Buffer lesen
        if ReadFile(hSrcFile, ptrBuffer^, cbLen, cbRead, nil) then begin
          //-- wenn alle Ok weiter
          if cbLen = cbRead then begin
            //-- OutPut File erstellen
            hDestFile := CreateFile(ADestFile, GENERIC_READ or GENERIC_WRITE, 0,
              nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
            //-- Wenn Ok dann weiter
            if hDestFile <> INVALID_HANDLE_VALUE then begin
              //-- Die zuvor gelesenen Daten in das Output File schreiben
              result := WriteFile(hDestFile, ptrBuffer^, cbLen, cbWritten, nil);
              //-- OutPut File schließen
              CloseHandle(hDestFile);
            end; //-- if hDestFile <> INVALID_HANDLE_VALUE then begin
          end; //-- if cbLen = cbRead then begin
        end; //-- if ReadFile(hSrcFile, ptrBuffer^, cbLen, cbRead, nil) then begin
        FreeMem(ptrBuffer, cbLen);
      end; //-- if SetFilePointer(hSrcFile, AStartOffset, nil, 0) <> $FFFFFFFF then begin
      CloseHandle(hSrcFile);
    end; //-- if hSrcFile <> INVALID_HANDLE_VALUE then begin
  end; //-- if cbLen > 0 then begin
end;
{$R-} {$Q-} {$I-}
Also Morgähn, und lg.

Luckie 28. Nov 2009 06:21

Re: File splitten
 
Zitat:

Zitat von uoeb7gp
Hallo Delphianer, bei D2 ist die Streambehandlung noch sehr jungfräulich implementiert.

Ich dachte das wäre der beste Compiler den Borland je entwickelt hätte und jetzt diese Aussage? ;)

Roookie 28. Nov 2009 15:17

Re: File splitten
 
Zitat:

Was ist die Maximalgröße der Dateien die du von bis Auslesen willst?
Solange ich dieses Problem noch habe, max. 2 GB. Danach schätzungsweise 4 GB Quelle und das Ziel 0..4 GB. Ziel kann auch 1 Byte lang sein.

Zitat:

Wieviel Memory hast Du zur Verfügung?
Unter Win98 kann ich auf fast 1 GB RAM zurückgreifen; WinME verschwendet doppelt so viel RAM; wenn nichts anderes läuft, braucht WinXP bei mir ca 130 MB; und mein funkelnagelneues Vista kommt nicht mal richtig mit 1 GB RAM aus.
Diese Antwort ging zum großen Teil an "alzaimar", der auch in diesem Thread (bisher) nichts Konstruktives beigetragen hat.
Ich denke mal, das Programm sollte ab 512 MB phys.RAM laufen können, mehr als 1 GB RAM (500 GB frei/nutzbar) aber auf keinen Fall.
Zitat:

Wie schnell soll das ganze Auslesen gegen (spielt Performance eine Rolle?)
Je schneller, desto besser. Aber Rekorde muß ich nicht brechen. Sicherheit/Korrektheit geht vor. Ich vermute aber mal, der begrenzende Faktor ist die Datenträger-Geschwindigkeit. Wenn ich es byteweise machen würde, wäre es aber definitiv zu lahm.

Zitat:

Lade die Datei in einen Stream. Setzt den Dateizeiger an die gewünschte Anfangsposition und kopiere dann die Gewünschte Anzahl Bytes in einen neuen Stream. Das wäre das Prinzip.
Hört sich gut an, aber hey: Ich bin Anfänger.

Zitat:

Geht das auch mit Delphi 2?
Das war wohl wiedermal nichts! So kommt man auch zu 4.492 Beiträgen.

Zitat:

So sollte es dennoch ohne Probleme funktionieren. ...
Na da hab' ich ja was, was ich meinem Compiler vorsetzen kann.
Ist zwar viel größer als gedacht, aber werd's mal testen.
Leider finde ich meine vorgeschlagenen Variablen-Namen darin nicht.
Werde ganz schön grübeln müssen, um da was zu kapieren (trotz guter Dokumentation).
Mir fällt jetzt schon auf: LongWord + LongBool habe ich in Delphi2 noch nie gesehen.
Kann ich an "ASourceFile: PChar; ADestFile: PChar" die Dateinamen als String übergeben?

Medium 28. Nov 2009 15:37

Re: File splitten
 
Zitat:

Zitat von Roookie
Leider finde ich meine vorgeschlagenen Variablen-Namen darin nicht.

Zeile für Zeile kommentiert... lässt du dein Steak auch in handliche, kaufrei schluckbare Stückchen schneiden weil du sonst davor kapitulieren musst?

himitsu 28. Nov 2009 15:45

Re: File splitten
 
Zitat:

Leider finde ich meine vorgeschlagenen Variablen-Namen darin nicht.
Werde ganz schön grübeln müssen, um da was zu kapieren (trotz guter Dokumentation).
Delphi-Quellcode:
ReadOffset(FirstByte, FirstByte + AnzahlBytes - 1, PChar(QuellFile), PChar(ZielFile));
oder du paßt den Code an
Delphi-Quellcode:
function ReadOffset(FirstByte, AnzahlBytes: LongWord; const QuellFile, ZielFile: String): Boolean;
und im Code dieses ersetzen
Code:
AStartOffset > FirstByte
AEndOffset  > FirstByte + AnzahlBytes - 1
ASourceFile > PChar(QuellFile)
ADestFile   > PChar(ZielFile)

bzw: cbLen := AnzahlBytes;

scrat1979 28. Nov 2009 15:52

Re: File splitten
 
Ich habe keine Ahnung, in wie fern in Delphi 2 schon implementiert sind, aber mit diesen methoden / eigenschaften müsstest Du es hingekommen:

StreamName.Create(...)
StreamName.Seek(...)
StreamName.CopyFrom(...) (im ZielDatei-Stream)
StreamName.Size;

Mehr Befehle wie diese zusammen mit 2 Streams brauchst Du nicht, um eine Datei in einem bestimmten Bereich zu zerlegen bzw. einen bestimmten "Bereich" herauszukopieren. Und danach den Speicher freigeben nicht vergessen. Sind wirklich nur wenige Zeilen und ist sehr einfach!

SCRaT


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz