Einzelnen Beitrag anzeigen

flow4.2

Registriert seit: 5. Sep 2007
5 Beiträge
 
#1

Daten in Datei einfügen bzw. löschen

  Alt 9. Apr 2010, 02:31
Besonders wenn man große Dateien hat und diese nicht in den Arbeitsspeicher laden kann (will, darf, muss...) ist es nicht ohne weiteres möglich Daten an einer beliebigen Stelle der Datei einzufügen (bzw. zu löschen)...


InsertData fügt Daten an einer beliebigen Position in einen Stream ein
Parameter:
- Stream: Die Datei als TStream
- P: Die Position an der die Daten eingefügt werden sollen
- Len: Die Länge der Daten, die eingefügt werden sollen
- Insert (optional): Die Daten die eingefügt werden sollen (wenn dieser Parameter nicht übergeben wird entsteht einfach ein "Loch" in der Datei - mit irgendwelchen Daten gefüllt)


RemoveData löscht Daten an einer beliebigen Position in einem Stream
Parameter
- Stream: Die Datei als TStream
- P: Die Position an der die Daten gelöscht werden sollen
- Len: Die Länge der Daten, die gelöscht werden sollen
- Removed (optional): Enthält die Daten die gelöscht wurden



Delphi-Quellcode:
procedure InsertData(Stream: TStream; const P, Len: Int64; Insert: TStream = nil);
const
  BufSize = $00010000;
var
  Buf: PChar;
  N: Integer;
  Size, Z: Int64;
begin
  GetMem(Buf, BufSize);
  try
    Z := 0;
    Size := Stream.Size;
    repeat
      if (Size-Z)-P < BufSize then N := (Size-Z)-P else N := BufSize;
      Stream.Position := Size-Z-N;
      Stream.ReadBuffer(Buf^, N);
      Stream.Position := Size-Z-N+Len;
      Stream.WriteBuffer(Buf^, N);
      Inc(Z, N);
    until (Size-Z) = P;
    if Insert <> nil then begin //Daten von Insert einfügen
      Stream.Position := P;
      Insert.Position := 0;
      if Len <= Insert.Size then Stream.CopyFrom(Insert, Len) else Stream.CopyFrom(Insert, 0);
    end;
  finally
    FreeMem(Buf, BufSize);
  end;
end;

Delphi-Quellcode:
procedure RemoveData(Stream: TStream; P: Int64; const Len: Int64; Removed: TStream = nil);
const
  BufSize = $00010000;
var
  Buf: PChar;
  N: Integer;
begin
  GetMem(Buf, BufSize);
  try
    if Removed <> nil then begin //Daten, die gelöscht werden in Removed kopieren
      Stream.Position := P;
      Removed.Position := 0;
      Removed.CopyFrom(Stream, Len);
    end;
    repeat
      if Stream.Size-P-Len < BufSize then N := Stream.Size-P-Len else N := BufSize;
      Stream.Position := P+Len;
      Stream.ReadBuffer(Buf^, N);
      Stream.Position := P;
      Stream.WriteBuffer(Buf^, N);
      Inc(P, N);
    until P = Stream.Size-Len;
    Stream.Size := Stream.Size - Len;
  finally
    FreeMem(Buf, BufSize);
  end;
end;


Dies ist mein erster Post hier überhaupt, also bitte ich schon mal prophylaktisch um Nachsicht...



jetzt wird TStream statt TFileStream verwendet

Satt Read und Write wird jetzt ReadBuffer und WriteBuffer verwendet
Optionale Paramter Insert und Removed hinzugefügt
BufSize auf $00010000 gesetzt
  Mit Zitat antworten Zitat