AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Datei in Streams zerstückeln

Ein Thema von TurboMartin · begonnen am 25. Mär 2007 · letzter Beitrag vom 25. Mär 2007
Antwort Antwort
TurboMartin

Registriert seit: 13. Feb 2006
Ort: Bad Honnef
765 Beiträge
 
Turbo Delphi für Win32
 
#1

Datei in Streams zerstückeln

  Alt 25. Mär 2007, 19:42
Ich möchte unter Verwendung diesen Codes eine Sehr große Datei in einen Stream laden. So weit so gut. Da sie sehr groß ist möchte ich dies nun in bestimmt große Blöcke zerkleinern. Das bedeutet, das ich in den Stream z.B. maximal 30MB geladen werden können. Dann soll saraus ein String gemacht werden, der dann in einer INI-Datei abgespeichert werden soll. Dies wieder holt sich dann so lange, bis die Ganze Datei in 30MB-Strings aufgeteilt ist.
Nun ist meine Frage, wie ich in einen Stream nur maximal 30MB lden kann, und diese dann nacher wieder zusammensetzten kann.
Tomorrow will be cancelled due to lack of interest.

  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#2

Re: Datei in Streams zerstückeln

  Alt 25. Mär 2007, 20:08
Delphi-Quellcode:
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
  BlockSize := 30*1024*1024;
  i := 0;
  while i < fs.Size do
  begin
    SetLength(S, BlockSize);
    //fs.Position := i;
    i2 := fs.Read(S[1], BlockSize);
    SetLength(S, i2);
    Inc(i, i2);

    // hier bekommst du in S jeweils maximal 30 MB-Teilstücke

  end;
finally
  fs.Free;
end;
du kannst auch sowas machen wie "gib mir Block mit Nummer":
Delphi-Quellcode:
BlockNummer := X;

fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
  BlockSize := 30*1024*1024;
  SetLength(Result, BlockSize);
  fs.Position := BlockNummer * BlockSize;
  i2 := fs.Read(Result[1], BlockSize);
  SetLength(Result, i2);

  // hier bekommst du in S jeweils den X-ten Block mit maximal 30 MB

finally
  fs.Free;
end;

// oder auch erst hier (wäre gut für 'ne Funktion)

Und zum zusammensetzen mußt du dann nur alle Teilstücker nacheinander wieder mit fs.Write in einen Stream reinschreiben.

PS: oder such mal nach Hier im Forum suchenFileSplittern, die machen ja sozusagen genau das Gleiche (nur halt mit 'nem anderem Zielformat der Teilstücke.

Aber warum will man eine sehr große Datei in vielen INIs speichern? (ich dank mal dafür gibt es besser geeignete Formate)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: Datei in Streams zerstückeln

  Alt 25. Mär 2007, 20:16
Zitat von TurboMartin:
Ich möchte unter Verwendung diesen Codes eine Sehr große Datei in einen Stream laden. So weit so gut.
Hi,
ich glaube da hast Du die Theorie von Streams noch nicht so richtig verstanden. Ein Stream ist eigentlich nur eine Art Verbindung zwischen zwei Punkten. Etwas unsauber kann man hier vielleicht besser von einem Kanal als Strom sprechen. Du kannst Daten zwischen zwei Endpunkten hin- und her bewegen. Beim Schreiben in den Stream landen die Daten nicht direkt im Stream, sondern dort, wo dieser Stream (Kanal) endet. Liest Du Daten aus dem Stream, so werden sie von diesem Endpunkt gelesen und nur über den Stream zu Dir transportiert. Der Stream selbst hält dabei nicht wirklich die Daten.
Wo diese gespeichert werden hängt mit der Implementierung der abstrakten Klasse TStream zusammen. Hier kommen Strings, Dateien, Speicherblöcke, aber auch alles andere in Frage.

Für eine Datei empfiehlt sich natürlich ein TFileStream. Erzeugst Du nun einen TFileStream, so wird zu keinem Zeitpunkt die ganze Datei in den Speicher geladen. Du erzeugst nur einen Kanal, der Daten in die Datei (bzw. aus ihr heraus) transportieren kann.

Zitat von TurboMartin:
Da sie sehr groß ist möchte ich dies nun in bestimmt große Blöcke zerkleinern. Das bedeutet, das ich in den Stream z.B. maximal 30MB geladen werden können.
Wenn Du mit Blöcken arbeiten willst, dann kannst Du einfach einen Puffer von 30 MByte erzeugen (z.B. ein String der Länge 30 * 1024 * 1024). Nun liest Du einfach die 30 MByte in diesen Puffer ein und arbeitest mit diesem weiter. Dein Stream wird dabei nur die Daten in den Speicher laden, die wirklich gerade gelesen werden. Dabei verwendet der Stream zwar einen Lesepuffer, aber auch dieser dürfte nicht all zu groß sein, so dass Du hier keine Sorgen haben musst.
Delphi-Quellcode:
var fs: TFileStream;
    buffer: String;
    count: Integer;
begin
  fs := TFileStream.Create(...);

  try
    // erzeugen eines 30 MByte Puffers
    setLength(buffer, 30 * 1024 * 1024);
    
    // Lesen der Datei in 30 Mbyte Blöcken
    repeat
      count := fs.Read(buffer[1], 30 * 1024 * 1024);
      
      // weiterarbeiten mit dem String
      // Achtung, Count gibt an wie viele Bytes vom Puffer
      // wirklich verwendet werden, der letzte String muss
      // nicht die vollen 30 MByte umfassen
      ....
    until count < 0;
  finally
    fs.Free;
  end;
Zitat von TurboMartin:
Nun ist meine Frage, wie ich in einen Stream nur maximal 30MB lden kann, und diese dann nacher wieder zusammensetzten kann.
Beim Zusammensetzen gilt das Gleiche wie gehabt (nur in schreibend). Du kannst die Blöcke von 30 MByte irgendwie verarbeiten. Dann bekommst Du irgendwas raus, das Du dann eben wieder in einen Stream schreibst. Handelt es sich bei dem Stream, in den Du schreibst um einen FileStream, landen die Daten direkt auf der Platte und nicht im Speicher (sehen wir von Caches und Lese/Schreibpuffer ab, die für Dich eh transparent sind).

Gruß Der Unwissende

[edit]
kein roter Kasten, sorry
[/edit]
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:40 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