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