Una soluzione molto semplice sarebbe quella di spostare (spostare) blocchi di dati dalla "posizione target compensare" verso BOF, e quindi tagliare (troncamento) gli avanzi:
--------------------------
|******|xxxxxx|yyyyyy|zzz|
--------------------------
BOF <-^ (target position offset)
--------------------------
|xxxxxx|yyyyyy|zzz|******|
--------------------------
^EOF
Dal @ David ha registrato un codice basato su TStream
, qui è un codice in base a "basso livello" I O pascal stile /:
function FileDeleteFromBOF(const FileName: string; const Offset: Cardinal): Boolean;
var
Buf: Pointer;
BufSize, FSize,
NumRead, NumWrite,
OffsetFrom, OffsetTo: Cardinal;
F: file;
begin
{$IOCHECKS OFF}
Result := False;
AssignFile(F, FileName);
try
FileMode := 2; // Read/Write
Reset(F, 1); // Record size = 1
FSize := FileSize(F);
if (IOResult <> 0) or (Offset >= FSize) then Exit;
BufSize := Min(Offset, 1024 * 64); // Max 64k - This value could be optimized
GetMem(Buf, BufSize);
try
OffsetFrom := Offset;
OffsetTo := 0;
repeat
Seek(F, OffsetFrom);
BlockRead(F, Buf^, BufSize, NumRead);
if NumRead = 0 then Break;
Seek(F, OffsetTo);
BlockWrite(F, Buf^, NumRead, NumWrite);
Inc(OffsetFrom, NumWrite);
Inc(OffsetTo, NumWrite);
until (NumRead = 0) or (NumWrite <> NumRead) or (OffsetFrom >= FSize);
// Truncate and set to EOF
Seek(F, FSize - Offset);
Truncate(F);
Result := IOResult = 0;
finally
FreeMem(Buf);
end;
finally
CloseFile(F);
end;
end;
In realtà, il riferimento al file sparse è piuttosto fuorviante. Non si tratta di ** cancellare ** N byte con offset 0, ma circa ** impostazione ** regione di 0..N-1 byte a zero (o qualunque valore del byte di riempimento preimpostato) – OnTheFly
@user Spiacente, che cos'è ingannevole? –
Sei fantastico! Grazie, David, l'ha fatto! – TheDude