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 | Capacitatea maximă de memorie de suport a fiecărui magazin intern de salvare, înainte de revarsare; implicit 64 MiB |
| SaveTemporaryDirectory | Director existent folosit pentru fișierele revarsate; o valoare goală folosește directorul temporar al procesului |
| LastSaveSpillCount | Numărul magazinelor interne de lucru care s-au revarsat în timpul celei mai recente conducte de salvare |
| LastSaveLargestMemoryBuffer | Cea mai mare capacitate individuală de memorie de suport observată în timpul celei mai recente conducte de salvare |
TPdfRandomAccessStore derivă din TStream și suportă citiri, scrieri, poziționări și dimensionări secvențiale normale, pe lângă I/O poziționat independent de cursor
Datele rămân într-un buffer de memorie dimensionat dinamic cât timp sfârșitul logic rămâne la nivelul lui sau sub MemoryLimit
Prima operație care depășește plafonul creează un fișier temporar exclusiv, copiază o singură dată octeții existenți, curăță bufferul de memorie și păstrează backend-ul de fișier pentru restul duratei de viață a magazinului
Mânerul temporar folosește fanioanele delete-on-close și de acces aleator, nu permite partajare și este eliminat la distrugerea normală sau la rollback-ul constructorului
Operațiile individuale sunt serializate de o secțiune critică internă; ReadAt și WriteAt sunt preferate când apelanții concurenți nu trebuie să concureze pentru cursorul secvențial
Un magazin poate fi transmis direct către LoadCustomDocument; callback-urile de bloc PDFium folosesc citiri poziționate și nu alterează cursorul magazinului
TPdf folosește politica configurată pentru salvările de bază, pentru fiecare spațiu de lucru de post-procesare al PDF-urilor salvate și pentru etapele intermediare de conversie de standarde, validare, criptare, DSS și pregătire PAdES
Repararea nativă incrementală a xref-stream-urilor citește ferestre cu dimensiune fixă din coadă și din dicționare, apoi aplică editările validate copiind intervalele neschimbate în bucăți delimitate
MemoryBytes raportează capacitatea bufferului de suport, nu dimensiunea logică a conținutuluiPeakMemoryBytes nu depășește niciodată MemoryLimitLastSaveLargestMemoryBuffer este cel mai mare magazin intern individual, nu suma magazinelor active simultanTBytes-urile temporare încă create de un parser, compresor, validator sau semnatar specificMemoryLimit trebuie să fie între zero și High(Integer)FPDF_FILEACCESS își păstrează limita de lungime de fișier de 4 GiB chiar și când magazinul de suport are în sine o dimensiune Int64 mai mareTemporaryFileName este doar pentru diagnostic; fișierul live este deschis exclusiv și nu trebuie redeschis de apelant
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;