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 | Kapasitas backing-memory maksimum setiap save store internal sebelum melimpah; bawaannya 64 MiB |
| SaveTemporaryDirectory | Directory yang sudah ada dan dipakai untuk file limpahan; nilai kosong memakai directory sementara proses |
| LastSaveSpillCount | Jumlah working store internal yang melimpah selama pipeline penyimpanan terakhir |
| LastSaveLargestMemoryBuffer | Kapasitas backing-memory tunggal terbesar yang teramati selama pipeline penyimpanan terakhir |
TPdfRandomAccessStore diturunkan dari TStream dan mendukung pembacaan, penulisan, seek, serta sizing sekuensial normal, di samping I/O terposisi yang independen dari cursor
Data tetap berada dalam buffer memori berukuran dinamis selama ujung logisnya berada pada atau di bawah MemoryLimit
Operasi pertama yang melampaui plafon akan membuat file sementara eksklusif, menyalin byte yang sudah ada satu kali, membersihkan buffer memori, dan memakai backend file untuk sisa umur store
Handle sementara memakai flag delete-on-close dan random-access, tidak mengizinkan sharing apa pun, dan dihapus saat destrusi normal maupun rollback konstruktor
Operasi individual diserialisasi oleh critical section internal; ReadAt dan WriteAt lebih disukai ketika pemanggil konkuren tidak boleh berebut cursor sekuensial
Store dapat diteruskan langsung ke LoadCustomDocument; callback blok PDFium memakai pembacaan terposisi dan tidak mengubah cursor store
TPdf memakai kebijakan yang dikonfigurasi untuk penyimpanan inti, setiap workspace post-processing PDF tersimpan, serta staging antara untuk konversi standards, validasi, enkripsi, DSS, dan PAdES
Perbaikan native inkremental atas xref-stream membaca jendela tail dan dictionary berukuran tetap, lalu menerapkan edit tervalidasi sambil menyalin rentang yang tidak berubah dalam chunk terbatas
MemoryBytes melaporkan kapasitas backing-buffer, bukan ukuran konten logisPeakMemoryBytes tidak pernah melampaui MemoryLimitLastSaveLargestMemoryBuffer adalah store internal tunggal terbesar, bukan jumlah semua store yang aktif bersamaanTBytes sementara yang masih dibuat oleh parser, compressor, validator, atau signer tertentuMemoryLimit harus berada antara nol dan High(Integer)FPDF_FILEACCESS Windows yang publik tetap mempertahankan batas panjang file 4 GiB meskipun backing store itu sendiri berukuran Int64 lebih besarTemporaryFileName hanya untuk diagnostik; file live dibuka secara eksklusif dan tidak boleh dibuka ulang oleh pemanggil
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;