void MoveFileBlock(FileDataBlock fileBlock, long dataOffset) { // First, determine whether the next file block needs to move before this one. long nextDataOffset; FileDataBlock nextFileBlock = GetNextFileDataBlock(fileBlock, dataOffset, out nextDataOffset); if (nextFileBlock != null && dataOffset + fileBlock.Length > nextFileBlock.FileOffset) { // The next block needs to move first, so do that now. MoveFileBlock(nextFileBlock, nextDataOffset); } // Now, move the block. if (fileBlock.FileOffset > dataOffset) { // Move the section to earlier in the file stream (done in chunks starting at the beginning of the section). byte[] buffer = new byte[COPY_BLOCK_SIZE]; for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length) { long readOffset = fileBlock.FileOffset + relativeOffset; int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset); _stream.Position = readOffset; _stream.Read(buffer, 0, bytesToRead); long writeOffset = dataOffset + relativeOffset; _stream.Position = writeOffset; _stream.Write(buffer, 0, bytesToRead); } } else { // Move the section to later in the file stream (done in chunks starting at the end of the section). byte[] buffer = new byte[COPY_BLOCK_SIZE]; for (long relativeOffset = 0; relativeOffset < fileBlock.Length; relativeOffset += buffer.Length) { int bytesToRead = (int)Math.Min(buffer.Length, fileBlock.Length - relativeOffset); long readOffset = fileBlock.FileOffset + fileBlock.Length - relativeOffset - bytesToRead; _stream.Position = readOffset; _stream.Read(buffer, 0, bytesToRead); long writeOffset = dataOffset + fileBlock.Length - relativeOffset - bytesToRead; _stream.Position = writeOffset; _stream.Write(buffer, 0, bytesToRead); } } // This block now points to a different position in the file. fileBlock.SetFileOffset(dataOffset); }