Утилитные и вспомогательные классы
Утилитарные и вспомогательные классы
Это руководство показывает, как использовать небольшие, специализированные вспомогательные классы, которые Aspose.PDF FOSS для .NET поставляются для типовых низкоуровневых задач: целочисленная математика, используемая криптографическими примитивами, конфигурация поиска по регулярным выражениям, оценка функций PostScript, обнаружение внешних шрифтов, извлечение под-путей векторных данных, измерение физического текста, редактирование буферизованных потоков содержимого, работа с большими потоками в памяти и отчёт о версии библиотеки. Эти классы сами по себе не являются точками входа, но они поддерживают более высокоуровневые операции с документами, текстом и рендерингом по всему API.
Вспомогательные функции целочисленной математики
MathExtensions — небольшой статический помощник, используемый внутри криптографических примитивов библиотеки, но доступный для общего использования всякий раз, когда требуется операция modulo, всегда возвращающая неотрицательный результат.
// Unlike the C# % operator, Mod never returns a negative value.
int wrapped = MathExtensions.Mod(-3, 5); // 2Конфигурация поиска по регулярным выражениям
RegexManager — статический класс, который настраивает движок регулярных выражений, используемый в операциях поиска текста, таких как TextFragmentAbsorber. Установите MatchTimeout, чтобы ограничить максимальное время выполнения шаблона, и включите NonBacktracking, чтобы использовать не-обратный движок regex для поисков, чувствительных к производительности.
using var doc = Document.Open(pdfBytes);
// Guard against runaway regex patterns.
RegexManager.MatchTimeout = TimeSpan.FromSeconds(5);
RegexManager.NonBacktracking = true;
var absorber = new TextFragmentAbsorber(@"\d{3}-\d{4}", true);
doc.Pages[1].Accept(absorber);Оценка функций PostScript
PostScriptEvaluator — статический класс, который вычисляет функции PDF типа 4 (PDF32000 §7.10.5) — программы-калькуляторы PostScript, встроенные в PDF, например используемые в некоторых определениях цветового пространства и затенения.
double[] inputs = { 0.5 };
// Evaluate a PostScript calculator program against the input array.
var outputs = PostScriptEvaluator.Evaluate("{ 2 mul }", inputs);Внешние пути поиска шрифтов
ExternalFontCache управляет папками, в которых производится поиск внешних (невстроенных) TrueType/OpenType faces во время рендеринга и конвертации. Используйте Instance, чтобы получить доступ к синглтону, GetDefaultFontsFolders — для просмотра встроенных мест поиска, и SetFontsFolders — чтобы добавить их или заменить.
var cache = ExternalFontCache.Instance;
var defaultFolders = cache.GetDefaultFontsFolders();
// reset: false appends to the existing search paths instead of replacing them.
cache.SetFontsFolders(new[] { @"C:\Fonts\Custom" }, reset: false);Извлечение векторных подпутей
GraphicsAbsorber посещает страницу и извлекает её нарисованные векторные подпути как элементы SubPath, каждая из которых содержит собственный ограничивающий Rectangle в координатах страницы. Это полезно для инспекции или измерения векторных рисунков без ручного разбора потока содержимого.
using var doc = Document.Open(pdfBytes);
var absorber = new GraphicsAbsorber();
absorber.Visit(doc.Pages[1]);
Console.WriteLine($"Elements found: {absorber.Elements.Count}");
foreach (var element in absorber.Elements)
{
if (element is SubPath subPath)
{
Rectangle bounds = subPath.Rectangle;
Console.WriteLine($"Sub-path bounds: [{bounds.LLX}, {bounds.LLY}, {bounds.URX}, {bounds.URY}]");
}
}Физическое измерение текстового сегмента
PhysicalTextSegment — проекция в координатах страницы поглощённого TextSegment. Доступ к нему можно получить через TextSegment.PhysicalSegment, чтобы измерить последовательность символов или прочитать её разрешённый TextState.
using var doc = Document.Open(pdfBytes);
var absorber = new TextFragmentAbsorber();
doc.Pages[1].Accept(absorber);
foreach (TextFragment fragment in absorber.TextFragments)
{
foreach (TextSegment segment in fragment.Segments)
{
PhysicalTextSegment physical = segment.PhysicalSegment;
var width = physical.MeasureSegment(segment.StartCharIndex, segment.EndCharIndex, true);
TextState state = physical.TextState;
}
}Буферизация правок потоков содержимого
ContentsAppender, доступный через Page.ContentsAppender, буферизует операторы для добавления в начало или конец потока содержимого страницы и фиксирует их за один проход с помощью UpdateData.
using var doc = Document.Open(pdfBytes);
Page page = doc.Pages[1];
page.ContentsAppender.AppendToBegin(new GSave());
page.ContentsAppender.AppendToEnd(new GRestore());
page.ContentsAppender.UpdateData();Большие потоки в памяти
OptimizedMemoryStream — это растущий поток в памяти, который может превышать ограничение в 2 ГБ для одного массива MemoryStream, храня данные в фиксированных блоках. Он наследуется от Stream, поэтому поддерживает обычные операции чтения, записи и перемещения.
using var stream = new OptimizedMemoryStream();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("large payload");
stream.Write(buffer, 0, buffer.Length);
bool canSeek = stream.CanSeek;
byte[] allBytes = stream.ToArray();Информация о версии библиотеки
BuildVersionInfo — статический класс, предоставляющий название продукта библиотеки и номера версий во время выполнения — полезно для диагностики и запросов в поддержку.
Console.WriteLine(BuildVersionInfo.Product);
Console.WriteLine(BuildVersionInfo.AssemblyVersion);
Console.WriteLine(BuildVersionInfo.FileVersion);Советы и лучшие практики
- Установите
RegexManager.MatchTimeoutперед выполнением поисков по недоверенным или пользовательским шаблонам, чтобы избежать катастрофической обратной трассировки. - Вызовите
ExternalFontCache.SetFontsFoldersсreset: true, когда нужно полностью заменить пути поиска по умолчанию, а не добавлять к ним. - Предпочитайте
OptimizedMemoryStreamвместоMemoryStreamпри буферизации очень больших документов или графических данных, которые могут превышать 2 ГБ. - Всегда завершайте пакет правок
ContentsAppenderс помощьюUpdateData()— буферизованные операторы не фиксируются в потоке контента до этого момента. GraphicsAbsorber.Elementsможет содержать экземплярыGraphicElement, отличные отSubPath; проверьте тип перед приведением.
Распространённые проблемы
| Проблема | Причина | Исправление |
|---|---|---|
| Поиск по регулярному выражению зависает на сложных шаблонах | Таймаут не настроен на RegexManager | Установите RegexManager.MatchTimeout перед выполнением TextFragmentAbsorber поисков |
Изменения потока содержимого от ContentsAppender не отображаются в сохранённом файле | UpdateData() никогда не вызывался | Вызовите UpdateData() после последнего вызова AppendToBegin/AppendToEnd |
| Пользовательские шрифты не обнаруживаются при рендеринге | Папка шрифтов не была зарегистрирована, или reset: true очистила ожидаемые значения по умолчанию | Вызовите ExternalFontCache.SetFontsFolders с правильным списком папок и значением reset |
OutOfMemoryException при буферизации очень большого вывода | MemoryStream достигла своего предела в 2 ГБ для одного массива | Используйте OptimizedMemoryStream, который хранит данные в блоках фиксированного размера |
FAQ
Почему MathExtensions.Mod отличается от оператора % C#?
MathExtensions.Mod всегда возвращает неотрицательный остаток, тогда как встроенный оператор % может возвращать отрицательное значение, если делимое отрицательно.
Как остановить слишком длительный поиск текста, основанный на регулярных выражениях?
Установите RegexManager.MatchTimeout в TimeSpan перед построением или запуском TextFragmentAbsorber, использующего шаблон regex.
Заменяет ли SetFontsFolders существующие пути поиска или добавляет к ним?
Это зависит от аргумента reset: передайте true, чтобы заменить текущий список папок, или false, чтобы добавить новые папки к нему.
Что именно извлекает GraphicsAbsorber?
Он извлекает нарисованные векторные подпути страницы как элементы SubPath, каждый с ограничивающим Rectangle в пространстве страницы, через GraphicsAbsorber.Visit.
Когда следует использовать OptimizedMemoryStream вместо MemoryStream?
Когда буферизованные данные могут приближаться к 2 ГБ или превышать его, поскольку MemoryStream опирается на один массив с этим жёстким ограничением.
API Reference Сводка
| Класс / Метод | Описание: |
|---|---|
MathExtensions.Mod | Помощник вычисления модуля неотрицательного целого, используемый в криптографических примитивах |
RegexManager.MatchTimeout | Тайм-аут, применяемый к поиску текста, основанному на регулярных выражениях |
RegexManager.NonBacktracking | Включает движок регулярных выражений без обратного отката |
PostScriptEvaluator.Evaluate | Выполняет функцию калькулятора PostScript типа 4 PDF |
ExternalFontCache.Instance | Одинарный доступ к внешнему кэшу шрифтов |
ExternalFontCache.GetDefaultFontsFolders | Возвращает папки поиска внешних шрифтов по умолчанию |
ExternalFontCache.SetFontsFolders | Добавляет или заменяет папки поиска внешних шрифтов |
GraphicsAbsorber.Visit | Извлекает элементы векторной графики со страницы |
GraphicsAbsorber.Elements | Коллекция извлечённых элементов GraphicElement/SubPath items |
SubPath.Rectangle | Ограничивающий прямоугольник в пространстве страницы извлечённого подпути |
PhysicalTextSegment.MeasureSegment | Измеряет диапазон символов в физическом текстовом сегменте |
PhysicalTextSegment.TextState | Разрешённое состояние форматирования физического текстового сегмента |
ContentsAppender.AppendToBegin | Буферизует оператор, который будет добавлен в начало потока содержимого страницы |
ContentsAppender.AppendToEnd | Буферизует оператор для добавления в поток содержимого страницы |
ContentsAppender.UpdateData | Фиксирует буферизованные операторы в поток содержимого |
OptimizedMemoryStream | Расширяемый поток в памяти, превышающий лимит MemoryStream в 2 ГБ |
BuildVersionInfo.Product | Наименование продукта работающей библиотеки |
BuildVersionInfo.AssemblyVersion | Версия сборки запущенной библиотеки |
BuildVersionInfo.FileVersion | Версия файла работающей библиотеки |