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 | Capacidad máxima de memoria de respaldo de cada almacén interno de guardado antes de volcar a disco; 64 MiB de forma predeterminada |
| SaveTemporaryDirectory | Directorio existente usado para los archivos de vuelco; un valor vacío usa el directorio temporal del proceso |
| LastSaveSpillCount | Número de almacenes internos de trabajo que volcaron a disco durante la canalización de guardado más reciente |
| LastSaveLargestMemoryBuffer | Mayor capacidad de memoria de respaldo individual observada durante la canalización de guardado más reciente |
TPdfRandomAccessStore deriva de TStream y admite lecturas, escrituras, búsquedas y dimensionamiento secuenciales normales, además de E/S posicionada independiente del cursor
Los datos permanecen en un búfer de memoria de tamaño dinámico mientras su final lógico se mantenga en o por debajo de MemoryLimit
La primera operación que cruza el techo crea un archivo temporal exclusivo, copia los bytes existentes una vez, limpia el búfer de memoria y conserva el backend de archivos por el resto de la vida útil del almacén
El manejador temporal usa las marcas de eliminación al cerrar y de acceso aleatorio, no permite compartir y se elimina en la destrucción normal o en la reversión del constructor
Las operaciones individuales se serializan mediante una sección crítica interna; se prefieren ReadAt y WriteAt cuando los llamadores concurrentes no deben competir por el cursor secuencial
Un almacén se puede pasar directamente a LoadCustomDocument; las devoluciones de llamada de bloque de PDFium usan lecturas posicionadas y no alteran el cursor del almacén
TPdf usa la política configurada para los guardados principales, cada área de trabajo de posprocesamiento del PDF guardado y las etapas intermedias de conversión de estándares, validación, cifrado, DSS y preparación de PAdES
La reparación nativa incremental de flujos xref lee ventanas de cola y de diccionario de tamaño fijo, y luego aplica ediciones validadas mientras copia los rangos sin cambios en fragmentos acotados
MemoryBytes informa la capacidad del búfer de respaldo, no el tamaño lógico del contenidoPeakMemoryBytes nunca supera MemoryLimitLastSaveLargestMemoryBuffer es el mayor almacén interno individual, no la suma de los almacenes activos simultáneosTBytes temporales que sigue creando un analizador, compresor, validador o firmante concretoMemoryLimit debe estar entre cero y High(Integer)FPDF_FILEACCESS de Windows conserva su límite de longitud de archivo de 4 GiB incluso cuando el almacén de respaldo en sí tiene un tamaño Int64 mayorTemporaryFileName es solo diagnóstico; el archivo activo se abre en exclusiva y el llamador no debe reabrirlo
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;