const PdfDefaultStorageMemoryLimit = 64 * 1024 * 1024;
type TPdfStorageBackend = (psbMemory, psbTemporaryFile);
constructor TPdfRandomAccessStore.Create(AMemoryLimit: Int64 = PdfDefaultStorageMemoryLimit; const ATemporaryDirectory: string = '');
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Seek(Offset: Int64; Origin: TSeekOrigin): Int64; override;
function Write(const Buffer; Count: Longint): Longint; override;
function ReadAt(Offset: Int64; var Buffer; Count: Longint): Longint;
function WriteAt(Offset: Int64; const Buffer; Count: Longint): Longint;
procedure CopyToStream(Destination: TStream; BufferSize: Integer = 1048576);
procedure Flush;
procedure SpillToDisk;
property Backend: TPdfStorageBackend;
property MemoryBytes: Int64;
property MemoryLimit: Int64;
property PeakMemoryBytes: Int64;
property Spilled: Boolean;
property TemporaryDirectory: string;
property TemporaryFileName: string;
property SaveMemoryLimit: Int64;
property SaveTemporaryDirectory: string;
property LastSaveSpillCount: Integer;
property LastSaveLargestMemoryBuffer: Int64;
| SaveMemoryLimit | Capacidade máxima de memória de suporte de cada armazenamento interno de gravação antes de transbordar; o padrão é 64 MiB |
| SaveTemporaryDirectory | Diretório existente usado para os ficheiros de transbordo; um valor vazio usa o diretório temporário do processo |
| LastSaveSpillCount | Número de armazenamentos de trabalho internos que transbordaram durante o pipeline de gravação mais recente |
| LastSaveLargestMemoryBuffer | Maior capacidade de memória de suporte única observada durante o pipeline de gravação mais recente |
TPdfRandomAccessStore deriva de TStream e suporta leituras sequenciais normais, escritas, seeks e dimensionamento, além de E/S posicionada independente do cursor
Os dados permanecem num buffer de memória de tamanho dinâmico enquanto o fim lógico se mantém em MemoryLimit ou abaixo dele
A primeira operação que ultrapassa o teto cria um ficheiro temporário exclusivo, copia os bytes existentes uma única vez, limpa o buffer de memória e mantém o backend de ficheiro durante o resto do tempo de vida do armazenamento
O handle temporário usa flags delete-on-close e de acesso aleatório, não permite partilha e é removido na destruição normal ou na reversão do construtor
As operações individuais são serializadas por uma secção crítica interna; ReadAt e WriteAt são preferidas quando chamadores concorrentes não podem competir pelo cursor sequencial
Um armazenamento pode ser passado diretamente a LoadCustomDocument; os callbacks de bloco do PDFium usam leituras posicionadas e não alteram o cursor do armazenamento
O TPdf usa a política configurada para gravações do núcleo, cada espaço de trabalho de pós-processamento do PDF gravado e preparação intermédia de conversão de standards, validação, encriptação, DSS e PAdES
A reparação nativa incremental de xref-stream lê janelas de tamanho fixo da cauda e de dicionários, depois aplica edições validadas enquanto copia intervalos inalterados em blocos limitados
MemoryBytes reporta a capacidade do buffer de suporte e não o tamanho lógico do conteúdoPeakMemoryBytes nunca excede MemoryLimitLastSaveLargestMemoryBuffer é o maior armazenamento interno único, não a soma dos armazenamentos ativos em simultâneoTBytes temporários ainda criados por um parser, compressor, validador ou assinante específicoMemoryLimit tem de estar entre zero e High(Integer)FPDF_FILEACCESS do Windows mantém o seu limite de comprimento de ficheiro de 4 GiB mesmo quando o armazenamento de suporte tem um tamanho Int64 maiorTemporaryFileName é apenas para diagnóstico; o ficheiro ativo é aberto em exclusivo e não deve ser reaberto pelo chamador
var
Store: TPdfRandomAccessStore;
begin
Pdf.SaveMemoryLimit := 16 * 1024 * 1024;
Pdf.SaveTemporaryDirectory := TPath.GetTempPath;
Pdf.SaveAs('output.pdf');
Log(Pdf.LastSaveSpillCount, Pdf.LastSaveLargestMemoryBuffer);
Store := TPdfRandomAccessStore.Create(4 * 1024 * 1024);
try
Store.CopyFrom(SourceStream, SourceStream.Size);
Store.Position := 0;
Pdf.LoadCustomDocument(Store, False);
finally
Pdf.Active := False;
Store.Free;
end;
end;