Klasy narzędziowe i pomocnicze
Klasy narzędziowe i pomocnicze
Ten przewodnik pokazuje, jak używać małych, wyspecjalizowanych klas pomocniczych, które Aspose.PDF FOSS dla .NET udostępnia do typowych zadań niskiego poziomu: arytmetyka całkowitoliczbowa używana przez prymitywy bezpieczeństwa, konfiguracja wyszukiwania regex, ocena funkcji PostScript, wykrywanie zewnętrznych czcionek, wyodrębnianie podścieżek wektorów, pomiar fizyczny tekstu, edycje buforowanych strumieni treści, duże strumienie w pamięci oraz raportowanie wersji biblioteki. Te klasy nie są samodzielnymi punktami wejścia, ale wspierają operacje dokumentów, tekstu i renderowania wyższego poziomu w całym API.
Pomocnicy arytmetyki całkowitoliczbowej
MathExtensions jest małym statycznym pomocnikiem używanym wewnętrznie przez prymitywy bezpieczeństwa biblioteki, ale jest dostępny do ogólnego użytku, gdy potrzebujesz operacji modulo, która zawsze zwraca nieujemny wynik.
// Unlike the C# % operator, Mod never returns a negative value.
int wrapped = MathExtensions.Mod(-3, 5); // 2Konfiguracja wyszukiwania regex
RegexManager jest statyczną klasą, która konfiguruje silnik wyrażeń regularnych używany przez operacje wyszukiwania tekstu, takie jak TextFragmentAbsorber. Ustaw MatchTimeout, aby ograniczyć czas działania wzorca, i włącz NonBacktracking, aby używać silnika regex bez backtrackingu w wyszukiwaniach wrażliwych na wydajność.
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);Ewaluacja funkcji PostScript
PostScriptEvaluator jest statyczną klasą, która ocenia funkcje PDF typu 4 (PDF32000 §7.10.5) — programy kalkulatorowe PostScript osadzone w PDF, takie jak te używane w niektórych definicjach przestrzeni kolorów i cieniowania.
double[] inputs = { 0.5 };
// Evaluate a PostScript calculator program against the input array.
var outputs = PostScriptEvaluator.Evaluate("{ 2 mul }", inputs);Zewnętrzne ścieżki wyszukiwania czcionek
ExternalFontCache zarządza folderami przeszukiwanymi w poszukiwaniu zewnętrznych (nieosadzonych) twarzy TrueType/OpenType podczas renderowania i konwersji. Użyj Instance, aby uzyskać dostęp do singletonu, GetDefaultFontsFolders, aby sprawdzić wbudowane lokalizacje wyszukiwania, oraz SetFontsFolders, aby dodać je lub zamienić.
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);Ekstrahowanie podścieżek wektorowych
GraphicsAbsorber odwiedza stronę i wyodrębnia jej namalowane podścieżki wektorowe jako elementy SubPath, z których każdy posiada własne ograniczenie Rectangle w przestrzeni strony. Jest to przydatne do inspekcji lub pomiaru grafiki wektorowej bez ręcznego parsowania strumienia zawartości.
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}]");
}
}Fizyczny pomiar segmentu tekstu
PhysicalTextSegment jest projekcją w przestrzeni strony zaabsorbowanego TextSegment. Uzyskaj do niego dostęp przez TextSegment.PhysicalSegment, aby zmierzyć ciąg znaków lub odczytać jego rozwiązany 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;
}
}Buforowanie edycji strumienia zawartości
ContentsAppender, osiągany przez Page.ContentsAppender, buforuje operatory, aby dołączyć na początku lub na końcu strumienia zawartości strony i zatwierdza je w jednym przebiegu przy użyciu 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();Duże strumienie w pamięci
OptimizedMemoryStream jest rosnącym strumieniem w pamięci, który może przekroczyć limit 2GB pojedynczej tablicy MemoryStream, przechowując dane w fragmentach o stałym rozmiarze. Dziedziczy po Stream, więc obsługuje typowe operacje odczytu, zapisu i przesuwania.
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();Informacje o wersji biblioteki
BuildVersionInfo jest klasą statyczną udostępniającą nazwę produktu biblioteki oraz numery wersji w czasie wykonywania — przydatną do diagnostyki i zgłoszeń wsparcia.
Console.WriteLine(BuildVersionInfo.Product);
Console.WriteLine(BuildVersionInfo.AssemblyVersion);
Console.WriteLine(BuildVersionInfo.FileVersion);Wskazówki i najlepsze praktyki
- Ustaw
RegexManager.MatchTimeoutprzed uruchomieniem wyszukiwań na niezaufanych lub dostarczonych przez użytkownika wzorcach, aby uniknąć catastrophic backtracking. - Wywołaj
ExternalFontCache.SetFontsFolderszreset: true, gdy chcesz całkowicie zastąpić domyślne ścieżki wyszukiwania zamiast je dołączać. - Preferuj
OptimizedMemoryStreamzamiastMemoryStream, gdy buforujesz bardzo duże dokumenty lub dane obrazu, które mogą przekraczać 2GB. - Zawsze zakończ partię edycji
ContentsAppenderza pomocąUpdateData()— buforowane operatory nie są zatwierdzane w strumieniu treści do tego momentu. GraphicsAbsorber.Elementsmoże zawierać wystąpieniaGraphicElementinne niżSubPath; sprawdź typ przed rzutowaniem.
Typowe problemy
| Problem | Przyczyna | Rozwiązanie |
|---|---|---|
| Wyszukiwanie regex zawiesza się przy złożonych wzorcach | Nie skonfigurowano limitu czasu na RegexManager | Ustaw RegexManager.MatchTimeout przed uruchomieniem wyszukiwań TextFragmentAbsorber |
Edycje strumienia treści z ContentsAppender nie pojawiają się w zapisanym pliku | UpdateData() nigdy nie zostało wywołane | Wywołaj UpdateData() po ostatnim wywołaniu AppendToBegin/AppendToEnd call |
| Niestandardowe czcionki nie są wykrywane podczas renderowania | Folder czcionek nie został zarejestrowany, lub reset: true wyczyścił oczekiwane domyślne ustawienia | Wywołaj ExternalFontCache.SetFontsFolders z poprawną listą folderów oraz wartością reset |
OutOfMemoryException przy buforowaniu bardzo dużego wyjścia | MemoryStream osiągnął limit 2GB na pojedynczą tablicę | Użyj OptimizedMemoryStream, który przechowuje dane w fragmentach o stałym rozmiarze |
FAQ
Dlaczego MathExtensions.Mod różni się od operatora C# %?
MathExtensions.Mod zawsze zwraca nieujemną resztę, podczas gdy wbudowany operator % może zwrócić wartość ujemną, gdy dzielna jest ujemna.
Jak zatrzymać wyszukiwanie tekstu oparte na wyrażeniach regularnych, aby nie działało zbyt długo?
Ustaw RegexManager.MatchTimeout na TimeSpan przed konstruowaniem lub uruchamianiem TextFragmentAbsorber, który używa wzorca regex.
Czy SetFontsFolders zastępuje, czy dodaje do istniejących ścieżek wyszukiwania?
To zależy od argumentu reset: przekaż true, aby zastąpić bieżącą listę folderów, lub false, aby dodać nowe foldery do niej.
Co tak naprawdę wyodrębnia GraphicsAbsorber?
Wyodrębnia pomalowane wektorowe podścieżki strony jako elementy SubPath, z których każdy ma ograniczenie Rectangle w przestrzeni strony, poprzez GraphicsAbsorber.Visit.
Kiedy powinienem używać OptimizedMemoryStream zamiast MemoryStream?
Gdy buforowane dane mogą zbliżać się do 2GB lub je przekraczać, ponieważ MemoryStream jest oparty na pojedynczej tablicy o tym sztywnym limicie.
Podsumowanie API Reference
| Klasa / Metoda | Opis |
|---|---|
MathExtensions.Mod | Pomocnik modulo liczb całkowitych nieujemnych używany przez prymitywy bezpieczeństwa |
RegexManager.MatchTimeout | Limit czasu stosowany do wyszukiwań tekstowych opartych na regex |
RegexManager.NonBacktracking | Włącza silnik wyrażeń regularnych bez cofania |
PostScriptEvaluator.Evaluate | Oblicza funkcję kalkulatora PostScript typu 4 PDF |
ExternalFontCache.Instance | Dostęp singletonowy do zewnętrznej pamięci podręcznej czcionek |
ExternalFontCache.GetDefaultFontsFolders | Zwraca domyślne zewnętrzne foldery wyszukiwania czcionek |
ExternalFontCache.SetFontsFolders | Dodaje lub zastępuje zewnętrzne foldery wyszukiwania czcionek |
GraphicsAbsorber.Visit | Wyodrębnia elementy grafiki wektorowej ze strony |
GraphicsAbsorber.Elements | Zbiór wyodrębnionych elementów GraphicElement/SubPath |
SubPath.Rectangle | Prostokąt ograniczający w przestrzeni strony wyodrębnionej podścieżki |
PhysicalTextSegment.MeasureSegment | Mierzy zakres znaków fizycznego segmentu tekstu |
PhysicalTextSegment.TextState | Rozwiązany stan formatowania fizycznego segmentu tekstu |
ContentsAppender.AppendToBegin | Buforuje operator, który ma być dołączony na początku strumienia zawartości strony |
ContentsAppender.AppendToEnd | Buforuje operator, aby dodać go do strumienia zawartości strony |
ContentsAppender.UpdateData | Zatwierdza buforowane operatory w strumieniu zawartości |
OptimizedMemoryStream | Rozszerzalny strumień w pamięci, który przekracza limit MemoryStream 2GB |
BuildVersionInfo.Product | Nazwa produktu uruchomionej biblioteki |
BuildVersionInfo.AssemblyVersion | Wersja zestawu uruchomionej biblioteki |
BuildVersionInfo.FileVersion | Wersja pliku uruchomionej biblioteki |