바코드 작업에서 오류 처리 및 디버그 하는 방법 C

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

바코드 처리 파이프라인은 오류 메시지 없이 실패할 수 있으며, 결과가 0인 경우 '바코드가 없음'으로 오해되는 경우가 많습니다. 하지만 파일 손상, 암호로 보호된 PDF 또는 형식 불일치와 같은 문제가 원인일 수 있습니다. 적절한 로깅과 구조화된 오류 처리를 구현하면 이러한 오류를 발견하고 실행 가능한 진단 정보를 제공할 수 있습니다.

IronBarcode IronBarcode 네임스페이스에 형식화된 예외 계층 구조, 내장 로깅 API 및 자세한 BarcodeResult 속성을 제공합니다. 이러한 속성에는 감지된 형식, 디코딩된 값, 페이지 번호 및 각 디코딩 성공 시의 좌표가 포함됩니다.

이 가이드에서는 타입이 지정된 예외를 포착하고 해석하는 방법, 읽기 실패에서 진단 컨텍스트를 추출하는 방법, 구조화된 로깅을 활성화하는 방법, 배치 작업 중 오류를 격리하는 방법을 설명합니다.

빠른 시작: 바코드 오류 처리 및 진단 활성화

읽기/쓰기 호출을 IronBarcode의 유형화된 예외를 대상으로 하는 try-catch 블록으로 감싸고 조용한 실패 대신 실행 가능한 오류 메시지를 표면화하십시오.

  1. NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/BarCode 설치하기

    PM > Install-Package BarCode
  2. 다음 코드 조각을 복사하여 실행하세요.

    using IronBarCode;
    using IronBarCode.Exceptions;
    
    try
    {
        BarcodeResults results = BarcodeReader.Read("label.pdf");
        Console.WriteLine($"Found {results.Count} barcode(s)");
    }
    catch (IronBarCodeFileException ex)
    {
        Console.Error.WriteLine($"File error: {ex.Message}");
    }
  3. 실제 운영 환경에서 테스트할 수 있도록 배포하세요.

    무료 체험판으로 오늘 프로젝트에서 IronBarcode 사용 시작하기

    arrow pointer

IronBarcode 예외를 어떻게 포착하고 해석하나요?

가장 구체적인 예외부터 가장 일반적인 예외까지 IronBarcode 예외를 처리합니다. 파일 오류, PDF 암호 오류, 인코딩 오류와 같이 조치가 필요한 예외를 먼저 처리하는 catch 블록을 배치하고, 그 다음에 기본 유형을 배치합니다. IronBarcode 네임스페이스는 각각 특정 오류 모드에 해당하는 11가지 예외 유형을 정의합니다.

IronBarcode 예외 유형 — 원인 및 권장 수정
예외 유형트리거권장 수정
IronBarCodeFileException파일이 손상되었거나, 잠겨 있거나, 지원되지 않는 이미지 형식입니다.지원되는 이미지 형식인지, 잠겨 있지 않은지 파일을 검증하고, 파일이 없는 경우 FileNotFoundException 별도로 처리합니다.
IronBarCodePdfPasswordExceptionPDF가 암호로 보호되었거나 암호화된 경우PdfBarcodeReaderOptions를 통해 암호를 제공하거나 파일을 건너뛰고 로그를 남깁니다.
IronBarCodeEncodingException바코드 생성 중 일반적인 인코딩 실패입력 데이터가 대상 BarcodeWriterEncoding 제약과 일치하는지 확인합니다.
IronBarCodeContentTooLongEncodingException선택한 심볼로지의 문자 제한을 초과하는 경우데이터를 잘라내거나 용량이 더 큰 형식(QR, DataMatrix)으로 전환합니다.
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException숫자 전용 형식(EAN, UPC)에 숫자가 아닌 문자를 전달하는 경우입력을 정리하거나 알파벳 문자 형식(Code128, Code39)으로 전환합니다.
IronBarCodeUnsupportedRendererEncodingExceptionSelected BarcodeEncoding 은 IronBarcode에서 기록 불가능합니다.BarcodeEncoding 대신 BarcodeWriterEncoding 열거형을 사용합니다.
IronBarCodeParsingException구조화된 데이터(GS1-128)가 구문 분석 중 유효성 검사에 실패하는 경우구문 분석 전에 Code128GS1Parser.IsValid()를 사용하여 GS1 구조를 확인합니다.
IronBarCodeNativeException네이티브 상호 운용 레이어에서 오류 (누락된 DLL, 플랫폼 호환성 문제)플랫폼 전문 NuGet 패키지가 설치되어 있는지 확인합니다 (BarCode.Linux, BarCode.macOS).
IronBarCodeConfidenceThresholdException잘못된 신뢰도 임계값 인수를 읽기 옵션에 전달한 경우ConfidenceThreshold 가 0.0과 1.0 사이인지 확인합니다.
IronBarCodeUnsupportedException현재 컨텍스트에서 지원되지 않는 작업사용 중인 버전에서 기능 가용성을 확인하려면 변경 로그를 확인하십시오.
IronBarCodeException기본 유형 — 위의 일치하지 않는 IronBarcode 특정 오류를 포착합니다.전체 예외 세부 정보를 기록하고 조사를 위해 확대합니다.

when 절을 포함한 예외 필터를 사용하여 중복되는 예외 유형을 깊은 중첩 없이 라우팅하십시오. 파일이 누락된 경우 IronBarCodeFileException 대신 표준 System.IO.FileNotFoundException이 발생하므로, 이 경우를 위한 별도의 catch 블록을 포함하십시오:

입력

송장 번호를 인코딩하는 Code128 바코드(성공 경로)와 누락된 PDF의 내용을 나타내는 창고 라벨 바코드(실패 경로).

스캔한 송장 입력에 Code128 바코드 인코딩 INV-2024-7829가 사용되었습니다.
Code128 barcode representing the content of the missing warehouse-labels.pdf failure path input
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/exception-hierarchy.cs
using IronBarCode;
using IronBarCode.Exceptions;

// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";

try
{
    BarcodeResults results = BarcodeReader.Read(filePath);
    foreach (BarcodeResult result in results)
    {
        // Print the detected symbology and decoded value for each barcode found
        Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
    }
}
catch (IronBarCodePdfPasswordException ex)
{
    // PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
    Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
    // File is present but corrupted, locked, or in an unsupported format
    Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
    // Missing files throw FileNotFoundException, not IronBarCodeFileException
    Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
    // The when filter routes only missing-DLL errors here; other native exceptions
    // fall through to the IronBarCodeException block below
    Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
    // Base catch for any IronBarcode-specific error not matched by the blocks above
    Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
Imports IronBarCode
Imports IronBarCode.Exceptions

' Success path: valid file present on disk
Dim filePath As String = "scanned-invoice.png"
' Failure path: file does not exist → caught by FileNotFoundException below
' Dim filePath As String = "warehouse-labels.pdf"

Try
    Dim results As BarcodeResults = BarcodeReader.Read(filePath)
    For Each result As BarcodeResult In results
        ' Print the detected symbology and decoded value for each barcode found
        Console.WriteLine($"[{result.BarcodeType}] {result.Value}")
    Next
Catch ex As IronBarCodePdfPasswordException
    ' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
    Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")
Catch ex As IronBarCodeFileException
    ' File is present but corrupted, locked, or in an unsupported format
    Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")
Catch ex As FileNotFoundException
    ' Missing files throw FileNotFoundException, not IronBarCodeFileException
    Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}")
Catch ex As IronBarCodeNativeException When ex.Message.Contains("DLL")
    ' The when filter routes only missing-DLL errors here; other native exceptions
    ' fall through to the IronBarCodeException block below
    Console.Error.WriteLine($"Missing native dependency: {ex.Message}")
Catch ex As IronBarCodeException
    ' Base catch for any IronBarcode-specific error not matched by the blocks above
    Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")
End Try
$vbLabelText   $csharpLabel

산출

참고해 주세요유효한 파일은 디코딩된 바코드 유형 및 값으로 해석됩니다.

Code128 디코딩 성공 여부를 보여주는 콘솔 출력: [Code128] INV-2024-7829

파일이 누락되면 전용 catch 블록을 통해 라우팅되는 FileNotFoundException이 발생합니다.

콘솔 출력에는 warehouse-labels.pdf 파일이 누락되어 FileNotFoundException 오류가 표시됩니다.

when (ex.Message.Contains("DLL"))IronBarCodeNativeException 필터는 누락된 종속성 오류를 다른 네이티브 예외에 영향을 주지 않고 특정 핸들러로 전달합니다. 이 접근 방식은 플랫폼별 패키지가 누락될 수 있는 Docker 배포 환경에서 특히 유용합니다.

IronSoftware.Exceptions.LicensingException은 라이선스 키가 유효하지 않거나 누락된 경우 별도로 발생합니다. 이 예외는 개별 읽기 또는 쓰기 호출 시점이 아니라 애플리케이션 시작 시점에 처리해야 합니다.


읽기 실패 데이터에서 진단 정보를 추출하는 방법은 무엇입니까?

읽기 작업에서 결과가 하나도 반환되지 않는 경우는 예외가 아닙니다. 이는 빈 BarcodeResults 컬렉션을 생성합니다. 진단 컨텍스트는 입력 매개변수, 구성된 옵션 및 반환된 부분 결과를 검사하여 얻습니다.

BarcodeResult 객체는 BarcodeType, Value, PageNumberPoints (모서리 좌표) 등이 포함됩니다. 예상치 못한 결과가 나타난 경우, 먼저 BarcodeType을 예상 형식과 비교하여 확인하고 PageNumber을 검증하십시오.

입력

인보이스 번호를 인코딩한 Code128 BARCODE로, ExpectBarcodeTypesCode128QRCode로 설정하고, 철저한 스캔을 위해 ReadingSpeed.Detailed로 설정하여 읽습니다.

스캔한 송장 입력에 Code128 바코드 인코딩 INV-2024-7829가 사용되었습니다.
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/diagnostic-logging.cs
using IronBarCode;

string filePath = "scanned-invoice.png";

// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
    Speed = ReadingSpeed.Detailed,      // slower but more thorough — use ExtremeDetail for damaged images
    ExpectMultipleBarcodes = true       // scan the full image rather than stopping at the first match
};

BarcodeResults results = BarcodeReader.Read(filePath, options);

// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
    // Log the configured options alongside the warning so the cause is immediately actionable
    Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
    Console.Error.WriteLine($"  ExpectedTypes: {options.ExpectBarcodeTypes}");
    Console.Error.WriteLine($"  Speed: {options.Speed}");
    Console.Error.WriteLine($"  Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
    foreach (BarcodeResult result in results)
    {
        // Points contains the four corner coordinates of the barcode in the image;
        // use the first corner as a representative position indicator
        string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
        Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
            + $"(Page: {result.PageNumber}, Position: {pos})");
    }
}
Imports IronBarCode

Dim filePath As String = "scanned-invoice.png"

' Configure the reader to narrow the search to specific symbologies and use
' a thorough scan pass — narrows false positives and improves decode accuracy
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit scan to known formats
    .Speed = ReadingSpeed.Detailed,      ' slower but more thorough — use ExtremeDetail for damaged images
    .ExpectMultipleBarcodes = True       ' scan the full image rather than stopping at the first match
}

Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)

' An empty result is not an exception — it means no barcode matched the configured options
If results Is Nothing OrElse results.Count = 0 Then
    ' Log the configured options alongside the warning so the cause is immediately actionable
    Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")
    Console.Error.WriteLine($"  ExpectedTypes: {options.ExpectBarcodeTypes}")
    Console.Error.WriteLine($"  Speed: {options.Speed}")
    Console.Error.WriteLine($"  Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")
Else
    For Each result As BarcodeResult In results
        ' Points contains the four corner coordinates of the barcode in the image;
        ' use the first corner as a representative position indicator
        Dim pos As String = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")
        Console.WriteLine($"[{result.BarcodeType}] {result.Value} " &
                          $"(Page: {result.PageNumber}, Position: {pos})")
    Next
End If
$vbLabelText   $csharpLabel

산출

ExpectBarcodeTypes이 이미지의 BARCODE와 일치하면, 판독 결과는 유형, 값, 페이지 번호 및 위치를 반환합니다.

페이지 번호와 위치 좌표와 함께 Code128 디코딩이 성공적으로 완료되었음을 보여주는 콘솔 출력입니다.

ExpectBarcodeTypes에 실제 심볼이 포함되어 있지 않으면, 읽기 작업은 빈 결과를 반환합니다. [WARN] 블록에는 구성된 유형, 읽기 속도 및 권장되는 다음 조치가 기록됩니다.

콘솔 출력에 [WARN] Code128 이미지에 대해 ExpectBarcodeTypes를 Code39로 설정했을 때 바코드를 찾을 수 없음이라는 메시지가 표시됩니다.

진단 과정에서 두 가지 일반적인 패턴이 나타납니다. ExpectBarcodeTypes 설정이 좁은 상태에서 결과가 비어 있는 경우, BARCODE가 다른 심볼로지를 사용하고 있음을 의미하는 경우가 많습니다; BarcodeEncoding.All로 확장하면 이를 확인할 수 있습니다. 예상치 못한 디코딩 결과는 일반적으로 이미지 품질이 좋지 않음을 나타냅니다.

이미지 필터를 적용하고 읽기 속도를 늦춰 다시 시도하면 이러한 문제가 해결되는 경우가 많습니다. 또한 RemoveFalsePositive 옵션을 켜거나 끄면 잡음이 많은 배경에서 발생하는 유령 판독을 제거할 수 있습니다.

바코드 작업에 대한 자세한 로깅을 활성화하는 방법은 무엇입니까?

IronBarcode는 IronSoftware.Logger을 통해 내장 로깅 API를 제공합니다. 바코드 작업을 시작하기 전에 로깅 모드와 파일 경로를 설정하여 읽기 및 쓰기 파이프라인의 내부 진단 출력을 캡처하십시오.

입력

상세 로깅이 활성화된 상태에서 읽기 대상으로 사용되는 Code128 바코드 TIFF 이미지입니다.

로깅 예제의 문제 스캔 입력으로 Code128 바코드 인코딩 PROB-SCAN-999가 사용되었습니다.
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/enable-logging.cs
using IronBarCode;

// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory

// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Detailed,
    ExpectBarcodeTypes = BarcodeEncoding.All  // scan for every supported symbology
};

BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
Imports IronBarCode

' Enable IronBarcode's built-in logging — set BEFORE any read/write calls
' LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory

' All subsequent operations will write internal processing steps to the log file:
' image pre-processing stages, format detection attempts, and native interop calls
Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Detailed,
    .ExpectBarcodeTypes = BarcodeEncoding.All  ' scan for every supported symbology
}

Dim results As BarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
$vbLabelText   $csharpLabel

LoggingModes.All는 디버그 출력 및 파일 수준 로깅을 모두 캡처합니다. 로그 파일에는 이미지 전처리 단계, 형식 감지 시도, 네이티브 상호 운용 호출과 같은 내부 처리 단계가 기록되며, 이러한 단계는 공개 API를 통해 볼 수 없습니다.

구조화된 로깅 프레임워크(Serilog, NLog, Microsoft.Extensions.Logging)를 사용하는 프로덕션 파이프라인의 경우, IronBarcode 작업을 미들웨어 계층으로 감싸면 내장 로그 파일과 함께 구조화된 JSON 항목이 추가됩니다. 내장 로거는 지원 에스컬레이션에 유용한 일반 텍스트 진단 정보를 기록합니다; 구조화된 래퍼는 관찰 가능성 스택에 대한 쿼리 가능한 필드를 제공합니다.

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/structured-wrapper.cs
using IronBarCode;
using System.Diagnostics;

// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
    var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
    try
    {
        BarcodeResults results = BarcodeReader.Read(filePath, options);
        sw.Stop();
        // Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
        Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
            + $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        return results;
    }
    catch (Exception ex)
    {
        sw.Stop();
        // Emit a structured error entry to stderr with exception type, message, and elapsed time
        Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
            + $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
            + $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        throw; // rethrow so the caller's catch blocks still handle the exception normally
    }
}
Imports IronBarCode
Imports System.Diagnostics

' Lightweight wrapper that adds structured JSON observability to every read call.
' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
Function ReadWithDiagnostics(filePath As String, options As BarcodeReaderOptions) As BarcodeResults
    Dim sw As Stopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is included
    Try
        Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
        sw.Stop()
        ' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
        Console.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
        Return results
    Catch ex As Exception
        sw.Stop()
        ' Emit a structured error entry to stderr with exception type, message, and elapsed time
        Console.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
        Throw ' rethrow so the caller's catch blocks still handle the exception normally
    End Try
End Function
$vbLabelText   $csharpLabel

구조화된 출력은 로그 집계 도구와 직접 통합됩니다. 컨테이너화된 배포 환경에서 Pipe stdout를 Fluentd, Datadog 또는 CloudWatch로 전송합니다. 경과 시간 필드는 SLA 위반으로 이어지기 전에 성능 저하를 파악하는 데 도움이 됩니다.

산출

상세 로깅이 활성화된 상태에서 바코드 인식이 성공적으로 완료되었음을 보여주는 콘솔 출력과 로그 파일 경로입니다.

배치 바코드 처리 오류를 어떻게 디버깅하나요?

여러 파일을 처리할 때 각 읽기 작업을 별도의 try-catch 블록으로 분리하고, 각 파일의 결과를 기록하고, 종합 요약을 생성합니다. 파이프라인은 첫 번째 오류에서 멈추지 않고 실패를 거듭하더라도 계속 진행됩니다.

입력

scans/ 배치 디렉터리에 있는 5개의 Code128 BarCode 이미지 중 4개. 다섯 번째 파일(scan-05-broken.png)에는 파일 예외를 유발하는 유효하지 않은 바이트가 포함되어 있습니다.

Code128 barcode encoding ITEM-SQ-001

배치 1 — 스캔 1

Code128 barcode encoding ITEM-SQ-002

배치 1 — 스캔 2

Code128 barcode encoding ITEM-SQ-003

배치 1 — 스캔 3

Code128 barcode encoding ITEM-SQ-004

배치 1 — 스캔 4

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/batch-processing.cs
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;

// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";

// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,                                    // balances throughput vs accuracy
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
    ExpectMultipleBarcodes = true                                     // scan each file fully
};

// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();

foreach (string file in files)
{
    try
    {
        BarcodeResults results = BarcodeReader.Read(file, options);

        // Empty result is not an exception — the file was read but contained no matching barcode
        if (results == null || results.Count == 0)
        {
            emptyCount++;
            errors.Add((file, "No barcodes detected")); // record so caller can adjust options
            continue;
        }

        foreach (BarcodeResult result in results)
        {
            Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
        }
        successCount++;
    }
    catch (IronBarCodePdfPasswordException)
    {
        // PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
        failCount++;
        errors.Add((file, "Password-protected PDF"));
    }
    catch (IronBarCodeFileException ex)
    {
        // File is corrupted, locked, or in an unsupported image format
        failCount++;
        errors.Add((file, $"File error: {ex.Message}"));
    }
    catch (FileNotFoundException ex)
    {
        // File was in the directory listing but deleted before the read completed (race condition)
        failCount++;
        errors.Add((file, $"File not found: {ex.Message}"));
    }
    catch (IronBarCodeException ex)
    {
        // Catch-all for any other IronBarcode-specific errors not handled above
        failCount++;
        errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
    }
    catch (Exception ex)
    {
        // Unexpected non-IronBarcode error — log the full type for investigation
        failCount++;
        errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
    }
}

sw.Stop();

// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files:    {files.Length}");
Console.WriteLine($"Success:        {successCount}");
Console.WriteLine($"Empty reads:    {emptyCount}");
Console.WriteLine($"Failures:       {failCount}");
Console.WriteLine($"Elapsed:        {sw.Elapsed.TotalSeconds:F1}s");

if (errors.Any())
{
    Console.WriteLine("\n--- Error Details ---");
    foreach (var (errorFile, errorMsg) in errors)
    {
        Console.Error.WriteLine($"  {Path.GetFileName(errorFile)}: {errorMsg}");
    }
}
Imports IronBarCode
Imports IronBarCode.Exceptions
Imports System.Diagnostics

' Enable built-in logging for the entire batch run so internal processing steps
' are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "batch-run.log"

' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
Dim files As String() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)

Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Balanced,                                    ' balances throughput vs accuracy
    .ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit to known formats
    .ExpectMultipleBarcodes = True                                     ' scan each file fully
}

' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
Dim successCount As Integer = 0
Dim failCount As Integer = 0
Dim emptyCount As Integer = 0
Dim errors As New List(Of (File As String, Error As String))() ' per-file error context for root cause analysis
Dim sw As Stopwatch = Stopwatch.StartNew()

For Each file As String In files
    Try
        Dim results As BarcodeResults = BarcodeReader.Read(file, options)

        ' Empty result is not an exception — the file was read but contained no matching barcode
        If results Is Nothing OrElse results.Count = 0 Then
            emptyCount += 1
            errors.Add((file, "No barcodes detected")) ' record so caller can adjust options
            Continue For
        End If

        For Each result As BarcodeResult In results
            Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}")
        Next
        successCount += 1
    Catch ex As IronBarCodePdfPasswordException
        ' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
        failCount += 1
        errors.Add((file, "Password-protected PDF"))
    Catch ex As IronBarCodeFileException
        ' File is corrupted, locked, or in an unsupported image format
        failCount += 1
        errors.Add((file, $"File error: {ex.Message}"))
    Catch ex As FileNotFoundException
        ' File was in the directory listing but deleted before the read completed (race condition)
        failCount += 1
        errors.Add((file, $"File not found: {ex.Message}"))
    Catch ex As IronBarCodeException
        ' Catch-all for any other IronBarcode-specific errors not handled above
        failCount += 1
        errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))
    Catch ex As Exception
        ' Unexpected non-IronBarcode error — log the full type for investigation
        failCount += 1
        errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))
    End Try
Next

sw.Stop()

' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine(vbCrLf & "--- Batch Summary ---")
Console.WriteLine($"Total files:    {files.Length}")
Console.WriteLine($"Success:        {successCount}")
Console.WriteLine($"Empty reads:    {emptyCount}")
Console.WriteLine($"Failures:       {failCount}")
Console.WriteLine($"Elapsed:        {sw.Elapsed.TotalSeconds:F1}s")

If errors.Any() Then
    Console.WriteLine(vbCrLf & "--- Error Details ---")
    For Each errorDetail In errors
        Console.Error.WriteLine($"  {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}")
    Next
End If
$vbLabelText   $csharpLabel

산출

콘솔 출력에 배치 요약이 표시됩니다. 성공 4건, 실패 1건이며, 손상된 파일에 대한 오류 세부 정보가 표시됩니다.

실행 중에는 콘솔에 디코딩된 바코드마다 한 줄씩 출력되고, 그 뒤에 파일 수, 성공 횟수, 빈 읽기 횟수, 실패 횟수 및 경과 시간을 포함한 요약 정보가 표시됩니다. 오류는 해당 파일 이름과 실패 원인과 함께 나열됩니다.

이 프로세스는 성공(바코드를 찾아 디코딩함), 실패(파일은 읽었지만 바코드가 감지되지 않음), 그리고 예외 발생의 세 가지 결과 범주로 구분합니다. 이러한 구분은 중요합니다. 왜냐하면 빈 읽기와 실패에는 서로 다른 대응이 필요하기 때문입니다. 빈 읽기 작업에는 더 광범위한 형식 설정이 필요할 수 있으며, 실패는 종종 파일 누락, 리소스 잠김 또는 기본 종속성 누락과 같은 인프라 문제를 나타냅니다.

오류 목록은 근본 원인 분석을 지원하기 위해 파일별 컨텍스트를 유지합니다. CI/CD 파이프라인에서 이 출력을 구문 분석하여 종료 코드(완전 성공 시 0, failCount가 0보다 클 경우 0이 아닌 값)를 설정하거나 오류 세부 정보를 알림 시스템으로 전달합니다.

처리량을 높이려면 Multithreadedtrue로 설정하고, 사용 가능한 CPU 코어 수에 맞춰 MaxParallelThreads를 조정하여 병렬 처리를 활성화하십시오. Parallel.ForEach로 병렬 반복을 감싸고 오류 목록에 스레드 안전 컬렉션을 사용하여 파일별 격리를 유지합니다.


추가 자료

파이프라인이 프로덕션 단계에 진입하면 라이선스 옵션을 확인하세요 .

자주 묻는 질문

IronBarcode를 사용하여 바코드 작업의 오류를 어떻게 처리할 수 있나요?

IronBarcode는 타입 예외와 내장 로깅을 제공하여 바코드 작업 중 오류를 효율적으로 관리하고 처리하여 애플리케이션이 원활하게 실행되도록 보장합니다.

IronBarcode는 바코드 문제를 디버깅하기 위해 어떤 기능을 제공하나요?

IronBarcode는 진단 추출 및 프로덕션 준비 배치 오류 분리를 포함하여 개발자가 바코드 관련 문제를 효율적으로 식별하고 해결하는 데 도움을 줍니다.

바코드 처리 중 IronBarcode가 오류를 기록할 수 있나요?

네, IronBarcode에는 바코드 처리 중 오류 세부 정보를 포착하고 기록할 수 있는 내장 로깅 기능이 있어 디버깅을 더 쉽게 할 수 있습니다.

IronBarcode의 타입 예외란 무엇인가요?

IronBarcode의 타입 예외는 바코드 작업 문제에 대한 세부 정보를 제공하여 개발자가 문제를 쉽게 진단하고 수정할 수 있도록 하는 구체적인 오류 유형입니다.

IronBarcode는 배치 오류 분리를 어떻게 지원하나요?

IronBarcode는 프로덕션 준비 배치 오류 분리를 제공하여 잘못된 바코드 작업을 성공적인 작업과 분리하여 배치 처리에서 오류 관리를 간소화합니다.

IronBarcode를 사용하여 바코드 작업에서 진단 정보를 추출할 수 있는 방법이 있나요?

네, IronBarcode는 진단 추출 도구를 제공하여 개발자가 바코드 작업에 대한 세부 정보를 수집하여 문제 해결 및 오류 해결에 도움을 줍니다.

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'name'

Filename: sections/author_component.php

Line Number: 18

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 18
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'title'

Filename: sections/author_component.php

Line Number: 38

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 38
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'comment'

Filename: sections/author_component.php

Line Number: 48

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 48
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

시작할 준비 되셨나요?
Nuget 다운로드 2,143,620 | 버전: 2026.4 방금 출시되었습니다
Still Scrolling Icon

아직도 스크롤하고 계신가요?

빠른 증거를 원하시나요? PM > Install-Package BarCode
샘플을 실행하세요 실이 바코드로 변하는 모습을 지켜보세요.