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 | Максимальна ємність резервної пам’яті кожного внутрішнього сховища збереження перед виливом; типово 64 MiB |
| SaveTemporaryDirectory | Наявний каталог для файлів виливу; порожнє значення використовує тимчасовий каталог процесу |
| LastSaveSpillCount | Кількість внутрішніх робочих сховищ, які вилилися під час останнього конвеєра збереження |
| LastSaveLargestMemoryBuffer | Найбільша окрема ємність резервної пам’яті, спостережена під час останнього конвеєра збереження |
TPdfRandomAccessStore успадковує від TStream і підтримує звичайні послідовні читання, записи, пошук і зміну розміру окрім позиційованого вводу-виводу, незалежного від курсора
Дані лишаються в динамічно розміреному буфері пам’яті, поки його логічний кінець не перевищує MemoryLimit
Перша операція, що перетинає стелю, створює ексклюзивний тимчасовий файл, один раз копіює наявні байти, очищає буфер пам’яті і тримає файловий бекенд до кінця життя сховища
Тимчасовий дескриптор використовує прапорці delete-on-close і довільного доступу, не дозволяє спільного доступу та видаляється під час нормального знищення або відкочування конструктора
Окремі операції серіалізуються внутрішньою критичною секцією; ReadAt і WriteAt надають перевагу, коли паралельні викликачі не мають змагатися за послідовний курсор
Сховище можна передати напряму в LoadCustomDocument; блокові колбеки PDFium використовують позиційоване читання і не змінюють курсор сховища
TPdf використовує налаштовану політику для ядрових збережень, кожного робочого простору постобробки збереженого PDF і проміжного перетворення стандартів, валідації, шифрування, DSS і підготовки PAdES
Нативне інкрементальне відновлення xref-потоків читає вікна кінця та словників фіксованого розміру, потім застосовує перевірені правки, копіюючи незмінені діапазони обмеженими шматками
MemoryBytes звітує ємність резервного буфера, а не розмір логічного вмістуPeakMemoryBytes ніколи не перевищує MemoryLimitLastSaveLargestMemoryBuffer — це найбільше окреме внутрішнє сховище, а не сума одночасно активних сховищTBytes, які досі створює конкретний розбирач, компресор, валідатор чи підписувачMemoryLimit має бути між нулем і High(Integer)FPDF_FILEACCESS зберігає свій ліміт довжини файлу 4 GiB, навіть коли саме резервне сховище має більший розмір Int64TemporaryFileName лише для діагностики; живий файл відкрито ексклюзивно, і викликач не повинен відкривати його знову
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;