Büyük PDF'lerde ReadPdf Sırasında Yüksek Zirve Belleği

This article was translated from English: Does it need improvement?
Translated
View the article in English

Büyük bir PDF için yalnızca bir kez BarcodeReader.ReadPdf() çağrıldığında, talep edilen her sayfa ayarlanan DPI'de tarama için işlenir, böylece tepe bellek sayfa sayısı ve çözünürlük ile birlikte ölçeklenir, düz bir seviyede kalmaz. 248 sayfalık, 80MB dosyada 300 DPI'da bellek 3GB ile 8GB arasında çalıştı, 12GB'a kadar sıçradı, hafıza sınırlı ortamlarda başarısız olmaya yetecek kadar.

BarcodeReader.ReadPdf() kendisine verilen her sayfayı tek bir işlemde işler. Tam sayfa aralığı büyük, yüksek-DPI belgede bir defada okunduğunda, tüm bu sayfalar bellekle birlikte tutulur, bu nedenle zirve kullanımı sayfa setinin boyutuyla büyür. Bu, okuma toplu işlenmesinin nasıl yapıldığını yansıtır, IronBarcode'un teyit edilmiş bir hatası değildir.

Çözüm

1. Sabit sayfa parçaları halinde okuyun

Belgeleri sabit sayfa parçalarına bölmek için PdfBarcodeReaderOptions.PageNumbers kullanın, böylece her seferinde yalnızca bir parça bellekte kalır. Daha küçük bir chunkSize tepe belleği düşürür ancak daha fazla geçiş ekler, bu yüzden bunu ortamın bellek sınırına göre ayarlayın.

var barcodeMetadata = new List<BarcodeResult>();
var pageChunks = Enumerable.Range(1, pdf.PageCount)
    .GroupBy(i => i / 50)
    .Select(g => g.ToArray())
    .ToList();
foreach (var chunk in pageChunks)
{
    var readerOptions = new PdfBarcodeReaderOptions
    {
        ExpectMultipleBarcodes = true,
        ExpectBarcodeTypes = IronBarCode.BarcodeEncoding.AllOneDimensional,
        Speed = ReadingSpeed.Detailed,
        ScanMode = BarcodeScanMode.OnlyDetectionModel,
        DPI = 300,
        PageNumbers = chunk
    };
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}");
    var chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions);
    if (chunkResult != null && chunkResult.Count > 0)
    {
        barcodeMetadata.AddRange(chunkResult);
    }
    // Optional memory pressure relief
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}");
var barcodeMetadata = new List<BarcodeResult>();
var pageChunks = Enumerable.Range(1, pdf.PageCount)
    .GroupBy(i => i / 50)
    .Select(g => g.ToArray())
    .ToList();
foreach (var chunk in pageChunks)
{
    var readerOptions = new PdfBarcodeReaderOptions
    {
        ExpectMultipleBarcodes = true,
        ExpectBarcodeTypes = IronBarCode.BarcodeEncoding.AllOneDimensional,
        Speed = ReadingSpeed.Detailed,
        ScanMode = BarcodeScanMode.OnlyDetectionModel,
        DPI = 300,
        PageNumbers = chunk
    };
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}");
    var chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions);
    if (chunkResult != null && chunkResult.Count > 0)
    {
        barcodeMetadata.AddRange(chunkResult);
    }
    // Optional memory pressure relief
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}");
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports IronBarCode

Dim barcodeMetadata As New List(Of BarcodeResult)()
Dim pageChunks = Enumerable.Range(1, pdf.PageCount) _
    .GroupBy(Function(i) i \ 50) _
    .Select(Function(g) g.ToArray()) _
    .ToList()

For Each chunk In pageChunks
    Dim readerOptions As New PdfBarcodeReaderOptions With {
        .ExpectMultipleBarcodes = True,
        .ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional,
        .Speed = ReadingSpeed.Detailed,
        .ScanMode = BarcodeScanMode.OnlyDetectionModel,
        .DPI = 300,
        .PageNumbers = chunk
    }
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}")
    Dim chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions)
    If chunkResult IsNot Nothing AndAlso chunkResult.Count > 0 Then
        barcodeMetadata.AddRange(chunkResult)
    End If
    ' Optional memory pressure relief
    GC.Collect()
    GC.WaitForPendingFinalizers()
Next

Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}")
$vbLabelText   $csharpLabel

Her yineleme, sadece PageNumbers içinde adlandırılan sayfaları okur, bu nedenle bellek tüm dosya boyunca birikmek yerine parçalar arasında düşer.

2. PDF akışını önbelleğe alın ve konumunu sıfırlayın

Akışı döngüden önce bir kez yerel bir değişkene okuyun ve sonra her parça için geri sarın. Stream özelliği her erişimde tahsis edebilir, bu yüzden bunu var pdfStream = pdf.Stream; içinde depolayın ve her parça okumadan önce pdfStream.Seek(0, SeekOrigin.Begin) çağırın.

3. Okuyucu seçeneklerini bir kez oluşturun

PdfBarcodeReaderOptions döngü dışında kurun ve her döngüde taze bir seçenekler nesnesi tahsis etmek yerine yalnızca PageNumbers parça başına değiştirin.

4. Sonuçlar listesini önceden boyutlandırın

Sonuçlar eklenirken iç dizi boyutlandırmasının tekrarını önlemek için tahmin edilen kapasitede sonuçlar listesini başlatın. Yineleme yaklaşık her on sayfa başına bir barkod başlangıç sayısı tahmin eder.

Curtis Chau
Teknik Yazar

Curtis Chau, Bilgisayar Bilimleri alanında Lisans Derecesine (Carleton Üniversitesi) sahip ve Node.js, TypeScript, JavaScript ve React konularında uzmanlaşmış ön uç geliştirmeyle ilgileniyor. Sezgisel ve estetik açıdan hoş kullanıcı arayüzleri oluşturma tutkunu, Curtis modern çerçevelerle çalışmayı ve iyi yapı...

Daha Fazla Oku
Başlamaya Hazır mısınız?
Nuget İndirmeler 2,317,217 | Sürüm: 2026.7 yeni yayınlandı
Still Scrolling Icon

Hâlâ Kaydırıyor Musunuz?

Hızlıca kanıt ister misiniz? PM > Install-Package BarCode
bir örnek çalıştır dizginizin barkoda dönüştüğünü izle.