Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Dateien zerlegen und zusammenfügen (https://www.delphipraxis.net/67471-dateien-zerlegen-und-zusammenfuegen.html)

bscreator 14. Apr 2006 21:58


Dateien zerlegen und zusammenfügen
 
Liebe Delphi-Fans,
habe folgendes Problem:

Mein aktuelles Projekt ist eine Software, die große Dateien in mehrere kleine Dateien zerlegen und auch wieder zu einer Datei zusammenfügen kann (Ja, ich weiß, das Rad immer wieder neu erfinden..., aber da ich schon seit längerer Zeit nicht mehr Delphi programmiert hab, muss ich wieder reinkommen).
Soviel zum Prolog...

In meinem Delphi 4 - Buch stehen ein paar Dinge, aber nichts richtig konkretes.

Problem 1:

Die Software soll möglichst wenig Arbeitsspeicher verwenden (auch wenns dadurch vielleicht bisl länger dauert...), das ist eigentlich die Vorraussetzung. Welche Methode würdet ihr da empfehlen ? (mit Streams, Memory Mapped Files, oder sonst was ?)



Problem 2:
Ein Stück quellcode liegt bei. Der Code zählt die Anzahl der Datensätze einer Datei:
Delphi-Quellcode:
    Exists := false;
    Pos := 0;

    if (FileExists(Edit1.Text)) =true then
    begin
        Res:=DisableWriteProtection(Edit1.Text);  //Schreibschutz aufheben
[b]         Edit4.Text := 'Waiting...';[/b]      
       
        try //Anzahl der Datensätze ermitteln

          AssignFile(F, Edit1.Text); //Dateipointer zuweisen
          Reset(F);                  //Datei öffnen
         
          Seek(F,0); //Satzzeiger an Anfang

          While (EOF(F)) = false do
          begin
              Pos := Pos+1;
              Seek(F, Pos);
          end;

          Edit4.Text := IntToStr(Pos);
        finally
           CloseFile(F);
        end;
Der Code funktioniert, auch die Anzahl der Datensätze werden korrekt zurückgegeben. Da der Benutzer aber nicht denken, soll, dass sich der Computer aufgehängt hat, soll im Edit4-Feld vor dem Beginn der while-Schleife ein 'Waiting' angezeigt werden. Nach Durchlauf der While-Schleife wird das 'Waiting' durch die Anzahl der Datensätze ersetzt.
Seltsamerweise wird im Edit4-Feld aber kein 'Waiting...' angezeigt, sondern nur die Anzahl der Datensätze, wenn die while-Schleife beendet ist. Hab schon versucht, den Befehl "Edit4.Text := 'Waiting'" an eine andere Stelle innerhalb des try-finally-Blocks zu setzen, aber auch das geht nicht. Was ist da los ?

Vielen, vielen Dank

Luckie 14. Apr 2006 22:02

Re: Dateien zerlegen und zusammenfügen
 
Mach mal ein Edit4.Refresh. Du musst deinem Fenster auch die Chance geben das Edit neu zu zeichnen.

Ansonsten: http://filesplitter.michael-puff.de

MisterNiceGuy 14. Apr 2006 22:36

Re: Dateien zerlegen und zusammenfügen
 
Das ist jetzt zawr OT, aber manch einer könnte sich mal 'ne Scheibe von der Formatierung und der Präsentation deines Beitrages abschneiden ;)

Zu deiner Problem: Versuche mal einen delay von 100 ms zu durchlaufen, bevor du den text des Edits änderst. Den Code zu dieser Procedure findest du hier: click me

3_of_8 14. Apr 2006 22:38

Re: Dateien zerlegen und zusammenfügen
 
Oder einfach ein Application.ProcessMessages; rein.

Hawkeye219 14. Apr 2006 22:52

Re: Dateien zerlegen und zusammenfügen
 
@bscreator
Noch einige Anmerkungen zu Deinem Code:

1.) Du solltest die Datei nur schließen, wenn sie auch geöffnet wurde. Die Anweisungen AssignFile und Reset müssen also vor dem TRY-Block stehen.
2.) Die Vergleiche mit True und False sind nicht notwendig und können in bestimmten Situationen sogar zu falschen Ergebnissen führen. Die Erklärung dafür findest Du hier.
3.) Delphi-Referenz durchsuchenFileSize :wink:

Die geänderte Version des Codes (incl. Luckies Vorschlag):

Delphi-Quellcode:
Exists := false;
Pos := 0;

if (FileExists(Edit1.Text)) then
begin
  Res := DisableWriteProtection(Edit1.Text);  //Schreibschutz aufheben
  Edit4.Text := 'Waiting...';
  Edit4.Refresh;

  AssignFile(F, Edit1.Text); //Dateipointer zuweisen
  Reset(F);                  //Datei öffnen
         
  try //Anzahl der Datensätze ermitteln

    Seek(F,0); //Satzzeiger an Anfang

    While (NOT EOF(F)) do
    begin
      Pos := Pos + 1;
      Seek(F, Pos);
    end;

    Edit4.Text := IntToStr(Pos);
 
  finally
    CloseFile(F);
  end;
end;
Gruß Hawkeye

[edit=Sharky]Session-ID aus dem Link entfernt. Mfg, Sharky[/edit]

marabu 15. Apr 2006 12:02

Re: Dateien zerlegen und zusammenfügen
 
Hallo.

Im gezeigten Code scheint F vom Typ File zu sein - sonst macht Seek() keinen Sinn. Beim Öffnen der Datei muss die Satzgröße 1 angegeben werden, sonst können nur Dateien korrekt verarbeitet werden, deren Größe ein Vielfaches von 128 (Standard-Satzgröße) ist. Das Schieben des Satzzeigers von einem zum nächsten Datensatz macht eigentlich keinen Sinn, da die Anzahl der Bytes in einer Datei nicht durch Abzählen, sondern direkt über die Metadaten des Dateisystems (FileSize - hallo Hawkeye) ermittelt werden kann. In keinem Fall ist es notwendig den Schreibschutz aufzuheben, da die Datei nur gelesen werden soll.

Für das Zerlegen beliebiger Dateien in mundgerechte Stücke ist TFileStream die bessere Lösung, da diese Komponente direkt auf dem Dateisystem aufsetzt. Die Implementierung von File und TextFile stand noch sehr stark unter dem Eindruck von CP/M.

Grüße vom marabu

Garfield 15. Apr 2006 13:51

Re: Dateien zerlegen und zusammenfügen
 
Delphi-Quellcode:
...
  Res := DisableWriteProtection(Edit1.Text);  //Schreibschutz aufheben
  ...
  Reset(F);                  //Datei öffnen
  ...
    Seek(F,0); //Satzzeiger an Anfang

    While (NOT EOF(F)) do
    begin
      Pos := Pos + 1;
      Seek(F, Pos);
    end;
    ...
Zum Lesen braucht man den Schreibschutz nicht aufheben. Besser dürfte sein, die Datei nur zum Lesen zu öffnen:
Delphi-Quellcode:
FileMode := 0;
Der Befehl gehört zwischen AssignFile und Reset. Sonst bekommt man bei schreibgeschützten Dateien bei Reset einen IOError.

Reset (F) öffnet die Datei und setzt den Zeiger auf den Anfang der Datei. Deshalb sollte Seek (F, 0) eigentlich überflüssig sein.

Die while-Schleife macht aus dem von marabu genannten Grund keinen Sinn.

bscreator 15. Apr 2006 14:00

Re: Dateien zerlegen und zusammenfügen
 
Application.ProcessMessages - Wie konnt ich das nur vergessen...

Ich weiß, manchmal red ich um den heißen Brei rum, ich versuch meine "Schwierigkeiten" mal so zu beschreiben:

1. Einen n-Byte großen Arbeitsspeicherbereich reservieren (als Dateipuffer)
2. n-Bytes aus der geöffneten Datei lesen und in den zuvor reservieren Arbeitsspeicherbereich übertragen (Brauch ich dann
Delphi-Quellcode:
File of Byte
3. Die n-Bytes vom Arbeitsspeicher in eine neu erstellte Datei übertragen

PS: Mit
Delphi-Quellcode:
GetMem(Typ of Integer)
kann man ja einen n-Byte großen Arbeitsspeicherbereich reservieren. Aber wird dieser
Speicherbereich dann "automatisch", sprich in diesem Fall als Dateipuffer, verwendet, oder brauch ich da eine Art Handle ?


4. Ich weiß nicht, irgendwie bereitet mir das Wort "Datensatz" Probleme. Meinen die mit Datensatz die einzelnen Bytes, aus
denen eine Datei besteht und ist jeder Datensatz 1 Byte groß ?

PS: Mit Edit4.Refresh hat es geklappt, FileMode := fmOpenRead hab ich jetzt auch schon eingefügt.

Ich versuchs erstmal mit den wahrscheinlich einfacheren Delphi-Funktionen und erst dann werd ich das ganze nochmal mit Windows-API Funktionen versuchen (erst stehen, dann fliegen)

Vielen Dank für eure schnellen und hilfreichen Antworten. Wünsch euch allen im Vorraus (hoffe, das bringt kein Unglück) ein frohes Ostereiersuchen.

Luckie 15. Apr 2006 14:22

Re: Dateien zerlegen und zusammenfügen
 
Warum benutzt du keine Streams? Oder die Windows-API Funbktionen?

bscreator 17. Apr 2006 09:29

Re: Dateien zerlegen und zusammenfügen
 
Ich werd das ganze jetzt mit Streams versuchen. Allerdings beantwortet mir weder die Delphi-Hilfe, noch das Delphi-Buch meine einfachen Fragen über Streams. Vielleicht könnt ihr mir helfen, bzw. meine Aussagen auf Richtigkeit hin kontrollieren:

1. Mit
Delphi-Quellcode:
TFileStream.Create
wird ein Stream, bzw. eine Datei auf der Festplatte angelegt
2. Mit
Delphi-Quellcode:
TMemoryStream.Create
wird ein Stream im Arbeitsspeicher angelegt

3. Um eine Datei zu kopieren, brauch ich TMemoryStream, um die Daten aus der Quelldatei in den Arbeitsspeicher zu verschieben und TFileStream, um die Daten aus dem Arbeitsspeicher auf die Festplatte zu speichern

Hab leider nicht allzuviel Ahnung über Streams.
Vielen Dank


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:05 Uhr.
Seite 1 von 2  1 2      

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