Утилитные и вспомогательные классы

Утилитные и вспомогательные классы

Утилитарные и вспомогательные классы

Это руководство показывает, как использовать небольшие, специализированные вспомогательные классы, которые 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Версия файла работающей библиотеки

См. также:

 Русский