Is it possible to delete bytes from the beginning of a file?

后端 未结 2 1225
后悔当初
后悔当初 2021-02-06 03:27

I know that I can efficiently truncate a file and remove bytes from the end of the file.

Is there a corresponding efficient way to truncate files by deleting content fr

2条回答
  •  借酒劲吻你
    2021-02-06 04:06

    A very simple solution would be to shift (move) blocks of data from the "target position offset" towards BOF, and then trim (truncate) the leftovers:

    --------------------------
    |******|xxxxxx|yyyyyy|zzz|
    --------------------------
    BOF  <-^ (target position offset)
    
    
    --------------------------
    |xxxxxx|yyyyyy|zzz|******|
    --------------------------
                      ^ EOF
    

    Since @David posted a code based on TStream, here is some code based on "low level" I/O pascal style:

    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;
    

提交回复
热议问题