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, תומך בקריאות, כתיבות, Seek וקביעת גודל סדרתיים רגילים, ובנוסף מציע I/O ממוקם שאינו תלוי בסמן
הנתונים נשארים בחוצץ זיכרון בגודל דינמי כל עוד הקצה הלוגי שלהם עומד על MemoryLimit או מתחתיו
הפעולה הראשונה שחוצה את התקרה יוצרת קובץ זמני בלעדי, מעתיקה את הבייטים הקיימים פעם אחת, מנקה את חוצץ הזיכרון, וממשיכה להשתמש במנגנון הקובץ עד תום חיי המאגר
הקובץ הזמני נפתח עם דגלי delete-on-close וגישה אקראית, אינו מאפשר שיתוף, ונמחק בהשמדה רגילה או בנסיגת בנאי
פעולות בודדות עוברות סריאליזציה באמצעות critical section פנימי; כאשר קוראים מקבילים לא צריכים להתחרות על הסמן הסדרתי, עדיף להשתמש ב־ReadAt וב־WriteAt
אפשר להעביר מאגר כזה ישירות אל LoadCustomDocument; ה-callbacks של בלוקים של PDFium משתמשים בקריאות ממוקמות ואינם משנים את סמן המאגר
TPdf משתמש במדיניות שהוגדרה עבור השמירות הבסיסיות, עבור כל סביבת עיבוד־המשך של PDF שנשמר, ועבור שלבי הביניים של המרת תקנים, אימות, הצפנה, DSS ו־PAdES
תיקון המקורי של xref-stream מצטבר קורא חלונות בגודל קבוע של הזנב ושל המילונים, ולאחר מכן מחיל עריכות מאומתות תוך העתקת הטווחים שלא השתנו במקטעים מוגבלים
MemoryBytes מדווח על קיבולת חוצץ התמיכה ולא על גודל התוכן הלוגיPeakMemoryBytes לעולם אינו חורג מ־MemoryLimitLastSaveLargestMemoryBuffer הוא המאגר הפנימי הבודד הגדול ביותר, ולא סכום המאגרים הפעילים בו־בזמןTBytes זמניים שעדיין נוצרים על ידי parser, compressor, validator או signer ספציפיMemoryLimit חייב להיות בין אפס לבין High(Integer)FPDF_FILEACCESS של Windows שומר על מגבלת אורך קובץ של 4 GiB גם כאשר למאגר התומך עצמו יש גודל Int64 גדול יותרTemporaryFileName מיועד לאבחון בלבד; הקובץ הפעיל נפתח באופן בלעדי ואין לפותחו שוב מצד הקורא
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;