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

后端 未结 2 1223
后悔当初
后悔当初 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 03:51

    As I read the question you are asking to remove content from a file starting from the beginning of the file. In other words you wish to delete content at the start of the file and shift the remaining content down.

    This is not possible. You can only truncate a file from the end, not from the beginning. You will need to copy the remaining content into a new file, or copy it down yourself within the same file.

    However you do it there is no shortcut efficient way to do this. You have to copy the data, for example as @kobik describes.

    Raymond Chen wrote a nice article on this topic: How do I delete bytes from the beginning of a file?


    Just for fun, here's a simple implementation of a stream based method to delete content from anywhere in the file. You could use this with a read/write file stream. I've not tested the code, I'll leave that to you!

    procedure DeleteFromStream(Stream: TStream; Start, Length: Int64);
    var
      Buffer: Pointer;
      BufferSize: Integer;
      BytesToRead: Int64;
      BytesRemaining: Int64;
      SourcePos, DestPos: Int64;
    begin
      SourcePos := Start+Length;
      DestPos := Start;
      BytesRemaining := Stream.Size-SourcePos;
      BufferSize := Min(BytesRemaining, 1024*1024*16);//no bigger than 16MB
      GetMem(Buffer, BufferSize);
      try
        while BytesRemaining>0 do begin
          BytesToRead := Min(BufferSize, BytesRemaining);
          Stream.Position := SourcePos;
          Stream.ReadBuffer(Buffer^, BytesToRead);
          Stream.Position := DestPos;
          Stream.WriteBuffer(Buffer^, BytesToRead);
          inc(SourcePos, BytesToRead);
          inc(DestPos, BytesToRead);
          dec(BytesRemaining, BytesToRead);
        end;
        Stream.Size := DestPos;
      finally
        FreeMem(Buffer);
      end;
    end;
    

提交回复
热议问题