바코드 작업에서 오류 처리 및 디버그 하는 방법 C
바코드 처리 파이프라인은 오류 메시지 없이 실패할 수 있으며, 결과가 0인 경우 '바코드가 없음'으로 오해되는 경우가 많습니다. 하지만 파일 손상, 암호로 보호된 PDF 또는 형식 불일치와 같은 문제가 원인일 수 있습니다. 적절한 로깅과 구조화된 오류 처리를 구현하면 이러한 오류를 발견하고 실행 가능한 진단 정보를 제공할 수 있습니다.
IronBarcode IronBarcode 네임스페이스에 형식화된 예외 계층 구조, 내장 로깅 API 및 자세한 BarcodeResult 속성을 제공합니다. 이러한 속성에는 감지된 형식, 디코딩된 값, 페이지 번호 및 각 디코딩 성공 시의 좌표가 포함됩니다.
이 가이드에서는 타입이 지정된 예외를 포착하고 해석하는 방법, 읽기 실패에서 진단 컨텍스트를 추출하는 방법, 구조화된 로깅을 활성화하는 방법, 배치 작업 중 오류를 격리하는 방법을 설명합니다.
빠른 시작: 바코드 오류 처리 및 진단 활성화
읽기/쓰기 호출을 IronBarcode의 유형화된 예외를 대상으로 하는 try-catch 블록으로 감싸고 조용한 실패 대신 실행 가능한 오류 메시지를 표면화하십시오.
-
NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/BarCode 설치하기
PM > Install-Package BarCode -
다음 코드 조각을 복사하여 실행하세요.
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}"); } -
실제 운영 환경에서 테스트할 수 있도록 배포하세요.
무료 체험판으로 오늘 프로젝트에서 IronBarcode 사용 시작하기
IronBarcode 에서 바코드 오류를 처리하고 진단 기능을 활성화하는 방법
- NuGet에서 IronBarcode 라이브러리 다운로드
- 특정 예외 유형을 대상으로 하는 try-catch 블록으로 읽기/쓰기 호출을 감쌉니다.
- 성공적인 읽기 후
BarcodeResults에서 빈 값이나 저신뢰 값을 검사합니다. IronSoftware.Logger를 활성화해 내부 진단 출력을 캡처합니다.- 계속-온-오류 논리를 사용하여 배치 작업에서 파일당 실패를 고립시킵니다.
IronBarcode 예외를 어떻게 포착하고 해석하나요?
가장 구체적인 예외부터 가장 일반적인 예외까지 IronBarcode 예외를 처리합니다. 파일 오류, PDF 암호 오류, 인코딩 오류와 같이 조치가 필요한 예외를 먼저 처리하는 catch 블록을 배치하고, 그 다음에 기본 유형을 배치합니다. IronBarcode 네임스페이스는 각각 특정 오류 모드에 해당하는 11가지 예외 유형을 정의합니다.
| 예외 유형 | 트리거 | 권장 수정 |
|---|---|---|
IronBarCodeFileException | 파일이 손상되었거나, 잠겨 있거나, 지원되지 않는 이미지 형식입니다. | 지원되는 이미지 형식인지, 잠겨 있지 않은지 파일을 검증하고, 파일이 없는 경우 FileNotFoundException 별도로 처리합니다. |
IronBarCodePdfPasswordException | PDF가 암호로 보호되었거나 암호화된 경우 | PdfBarcodeReaderOptions를 통해 암호를 제공하거나 파일을 건너뛰고 로그를 남깁니다. |
IronBarCodeEncodingException | 바코드 생성 중 일반적인 인코딩 실패 | 입력 데이터가 대상 BarcodeWriterEncoding 제약과 일치하는지 확인합니다. |
IronBarCodeContentTooLongEncodingException | 선택한 심볼로지의 문자 제한을 초과하는 경우 | 데이터를 잘라내거나 용량이 더 큰 형식(QR, DataMatrix)으로 전환합니다. |
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException | 숫자 전용 형식(EAN, UPC)에 숫자가 아닌 문자를 전달하는 경우 | 입력을 정리하거나 알파벳 문자 형식(Code128, Code39)으로 전환합니다. |
IronBarCodeUnsupportedRendererEncodingException | Selected 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의 내용을 나타내는 창고 라벨 바코드(실패 경로).
스캔된 송장.png (성공 경로)
warehouse-labels.pdf (오류 경로 - 디스크에 파일이 없습니다)
: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
산출
파일이 누락되면 전용 catch 블록을 통해 라우팅되는 FileNotFoundException이 발생합니다.
when (ex.Message.Contains("DLL"))의 IronBarCodeNativeException 필터는 누락된 종속성 오류를 다른 네이티브 예외에 영향을 주지 않고 특정 핸들러로 전달합니다. 이 접근 방식은 플랫폼별 패키지가 누락될 수 있는 Docker 배포 환경에서 특히 유용합니다.
IronSoftware.Exceptions.LicensingException은 라이선스 키가 유효하지 않거나 누락된 경우 별도로 발생합니다. 이 예외는 개별 읽기 또는 쓰기 호출 시점이 아니라 애플리케이션 시작 시점에 처리해야 합니다.
읽기 실패 데이터에서 진단 정보를 추출하는 방법은 무엇입니까?
읽기 작업에서 결과가 하나도 반환되지 않는 경우는 예외가 아닙니다. 이는 빈 BarcodeResults 컬렉션을 생성합니다. 진단 컨텍스트는 입력 매개변수, 구성된 옵션 및 반환된 부분 결과를 검사하여 얻습니다.
BarcodeResult 객체는 BarcodeType, Value, PageNumber 및 Points (모서리 좌표) 등이 포함됩니다. 예상치 못한 결과가 나타난 경우, 먼저 BarcodeType을 예상 형식과 비교하여 확인하고 PageNumber을 검증하십시오.
입력
인보이스 번호를 인코딩한 Code128 BARCODE로, ExpectBarcodeTypes를 Code128 및 QRCode로 설정하고, 철저한 스캔을 위해 ReadingSpeed.Detailed로 설정하여 읽습니다.
: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
산출
ExpectBarcodeTypes이 이미지의 BARCODE와 일치하면, 판독 결과는 유형, 값, 페이지 번호 및 위치를 반환합니다.
ExpectBarcodeTypes에 실제 심볼이 포함되어 있지 않으면, 읽기 작업은 빈 결과를 반환합니다. [WARN] 블록에는 구성된 유형, 읽기 속도 및 권장되는 다음 조치가 기록됩니다.
진단 과정에서 두 가지 일반적인 패턴이 나타납니다. ExpectBarcodeTypes 설정이 좁은 상태에서 결과가 비어 있는 경우, BARCODE가 다른 심볼로지를 사용하고 있음을 의미하는 경우가 많습니다; BarcodeEncoding.All로 확장하면 이를 확인할 수 있습니다. 예상치 못한 디코딩 결과는 일반적으로 이미지 품질이 좋지 않음을 나타냅니다.
이미지 필터를 적용하고 읽기 속도를 늦춰 다시 시도하면 이러한 문제가 해결되는 경우가 많습니다. 또한 RemoveFalsePositive 옵션을 켜거나 끄면 잡음이 많은 배경에서 발생하는 유령 판독을 제거할 수 있습니다.
바코드 작업에 대한 자세한 로깅을 활성화하는 방법은 무엇입니까?
IronBarcode는 IronSoftware.Logger을 통해 내장 로깅 API를 제공합니다. 바코드 작업을 시작하기 전에 로깅 모드와 파일 경로를 설정하여 읽기 및 쓰기 파이프라인의 내부 진단 출력을 캡처하십시오.
입력
상세 로깅이 활성화된 상태에서 읽기 대상으로 사용되는 Code128 바코드 TIFF 이미지입니다.
: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.")
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
구조화된 출력은 로그 집계 도구와 직접 통합됩니다. 컨테이너화된 배포 환경에서 Pipe stdout를 Fluentd, Datadog 또는 CloudWatch로 전송합니다. 경과 시간 필드는 SLA 위반으로 이어지기 전에 성능 저하를 파악하는 데 도움이 됩니다.
산출
배치 바코드 처리 오류를 어떻게 디버깅하나요?
여러 파일을 처리할 때 각 읽기 작업을 별도의 try-catch 블록으로 분리하고, 각 파일의 결과를 기록하고, 종합 요약을 생성합니다. 파이프라인은 첫 번째 오류에서 멈추지 않고 실패를 거듭하더라도 계속 진행됩니다.
입력
scans/ 배치 디렉터리에 있는 5개의 Code128 BarCode 이미지 중 4개. 다섯 번째 파일(scan-05-broken.png)에는 파일 예외를 유발하는 유효하지 않은 바이트가 포함되어 있습니다.
배치 1 — 스캔 1
배치 1 — 스캔 2
배치 1 — 스캔 3
배치 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
산출
실행 중에는 콘솔에 디코딩된 바코드마다 한 줄씩 출력되고, 그 뒤에 파일 수, 성공 횟수, 빈 읽기 횟수, 실패 횟수 및 경과 시간을 포함한 요약 정보가 표시됩니다. 오류는 해당 파일 이름과 실패 원인과 함께 나열됩니다.
이 프로세스는 성공(바코드를 찾아 디코딩함), 실패(파일은 읽었지만 바코드가 감지되지 않음), 그리고 예외 발생의 세 가지 결과 범주로 구분합니다. 이러한 구분은 중요합니다. 왜냐하면 빈 읽기와 실패에는 서로 다른 대응이 필요하기 때문입니다. 빈 읽기 작업에는 더 광범위한 형식 설정이 필요할 수 있으며, 실패는 종종 파일 누락, 리소스 잠김 또는 기본 종속성 누락과 같은 인프라 문제를 나타냅니다.
오류 목록은 근본 원인 분석을 지원하기 위해 파일별 컨텍스트를 유지합니다. CI/CD 파이프라인에서 이 출력을 구문 분석하여 종료 코드(완전 성공 시 0, failCount가 0보다 클 경우 0이 아닌 값)를 설정하거나 오류 세부 정보를 알림 시스템으로 전달합니다.
처리량을 높이려면 Multithreaded를 true로 설정하고, 사용 가능한 CPU 코어 수에 맞춰 MaxParallelThreads를 조정하여 병렬 처리를 활성화하십시오. Parallel.ForEach로 병렬 반복을 감싸고 오류 목록에 스레드 안전 컬렉션을 사용하여 파일별 격리를 유지합니다.
추가 자료
- IronBarcode 튜토리얼: 바코드 읽기 : 바코드 읽기의 전 과정을 단계별로 안내합니다.
- 오탐 방지 : 노이즈가 많은 이미지에서 잘못된 판독값을 줄입니다.
- 이미지 보정 방법 : 판독 정확도를 향상시키는 필터.
- Docker 설정 가이드: 올바른 네이티브 종속성을 사용한 컨테이너화된 배포.
- BarcodeReaderOptions API 참조 : 전체 구성 문서입니다.
- IronBarcode 변경 로그 : 버전별 수정 사항 및 기능 추가 사항.
파이프라인이 프로덕션 단계에 진입하면 라이선스 옵션을 확인하세요 .
자주 묻는 질문
IronBarcode를 사용하여 바코드 작업의 오류를 어떻게 처리할 수 있나요?
IronBarcode는 타입 예외와 내장 로깅을 제공하여 바코드 작업 중 오류를 효율적으로 관리하고 처리하여 애플리케이션이 원활하게 실행되도록 보장합니다.
IronBarcode는 바코드 문제를 디버깅하기 위해 어떤 기능을 제공하나요?
IronBarcode는 진단 추출 및 프로덕션 준비 배치 오류 분리를 포함하여 개발자가 바코드 관련 문제를 효율적으로 식별하고 해결하는 데 도움을 줍니다.
바코드 처리 중 IronBarcode가 오류를 기록할 수 있나요?
네, IronBarcode에는 바코드 처리 중 오류 세부 정보를 포착하고 기록할 수 있는 내장 로깅 기능이 있어 디버깅을 더 쉽게 할 수 있습니다.
IronBarcode의 타입 예외란 무엇인가요?
IronBarcode의 타입 예외는 바코드 작업 문제에 대한 세부 정보를 제공하여 개발자가 문제를 쉽게 진단하고 수정할 수 있도록 하는 구체적인 오류 유형입니다.
IronBarcode는 배치 오류 분리를 어떻게 지원하나요?
IronBarcode는 프로덕션 준비 배치 오류 분리를 제공하여 잘못된 바코드 작업을 성공적인 작업과 분리하여 배치 처리에서 오류 관리를 간소화합니다.
IronBarcode를 사용하여 바코드 작업에서 진단 정보를 추출할 수 있는 방법이 있나요?
네, IronBarcode는 진단 추출 도구를 제공하여 개발자가 바코드 작업에 대한 세부 정보를 수집하여 문제 해결 및 오류 해결에 도움을 줍니다.

