Introduction
계약서, 재무제표 또는 규제 신고서를 보관하는 기업은 해당 PDF를 보관 등급 형식인 PDF/A로 유지해야 합니다. 요구되는 적합성을 충족하지 못한 파일이 하나라도 섞이면 감사자는 전체 배치를 문제시할 수 있으며, 수개월 후에 비용이 많이 드는 재처리가 발생할 수 있습니다. 수백 개의 파일이 매일 들어오는 상황에서 수동 검사는 곧 비현실적이 됩니다.
GroupDocs.Metadata for .NET은 추측의 여지를 없애줍니다. 명확한 IsPdfA 플래그와 정확한 PdfFormat 열거형을 제공함으로써, 라이브러리는 단 한 줄로 문서가 어떤 PDF/A 레벨을 만족하는지, 그리고 만족한다면 구체적인 변형(예: PDF/A‑1b, PDF/A‑2u)이 무엇인지 알려줍니다. 이 튜토리얼에서는 해당 로직을 콘솔 앱에 적용하고, 웹 API로 노출하며, 배치 처리에 확장하는 방법을 보여줍니다.
이 가이드를 마치면 다음을 수행할 수 있습니다.
Metadata클래스로 PDF를 로드합니다.- 불리언 속성으로 PDF/A 적합성을 판단합니다.
- 적합한 파일에 대해 정확한 PDF/A 버전을 추출합니다.
- 체크를 배치 작업, API, 서버리스 함수 등 더 큰 워크플로에 통합합니다.
Why Accurate PDF/A Detection Is Crucial
신뢰할 수 있는 자동화 검사는 다음에 도움이 됩니다.
- 감사 준비 유지: 모든 보관 PDF가 ISO 19005 표준을 충족한다는 것을 규제 기관에 증명합니다.
- 시각적 일관성 보존: PDF/A는 폰트, 색상 및 레이아웃이 향후 뷰어에서도 동일하게 유지됨을 보장합니다.
- 수집 파이프라인 자동화: 비적합 파일이 문서 관리 시스템에 도달하기 전에 차단합니다.
- 비용이 많이 드는 재작업 방지: 조기 감지는 라이프사이클 후반에 발생할 수 있는 비용이 큰 배치 재검증을 예방합니다.
Prerequisites
- .NET 6.0 이상.
- GroupDocs.Metadata NuGet 패키지(최신 버전).
- 평가하려는 하나 이상의 PDF 파일.
- (선택) 임시 평가 라이선스 – GroupDocs 포털에서 얻을 수 있습니다.
Installation
새 콘솔 프로젝트를 만들고 패키지를 추가합니다:
dotnet new console -n DetectPdfA
cd DetectPdfA
dotnet add package GroupDocs.Metadata
Step 1 – Initialise the Metadata Engine
먼저 Metadata 클래스로 PDF를 엽니다. 생성자는 파일 형식을 자동으로 인식하므로 추가 매개변수가 필요하지 않습니다.
using GroupDocs.Metadata;
string pdfPath = "sample.pdf";
// 문서를 연다 – using 블록은 파일 핸들이 적절히 해제되도록 보장한다.
using (Metadata metadata = new Metadata(pdfPath))
{
// 이후 단계는 여기서 진행한다.
}
핵심 포인트: using 문은 네이티브 리소스를 즉시 해제하도록 하여 장기 실행 서비스에서 파일 핸들 누수를 방지합니다.
Step 2 – Get the PDF‑Specific Root Package
GroupDocs.Metadata는 각 형식에 대해 강력히 타입이 지정된 루트 객체를 제공합니다. PDF의 경우 PdfRootPackage를 요청하면 필요한 FileType 정보를 얻을 수 있습니다.
using GroupDocs.Metadata.Formats.Pdf;
// Step 1의 using 블록 내부
var root = metadata.GetRootPackage<PdfRootPackage>();
root.FileType에는 두 가지 관심 속성이 있습니다.
IsPdfA– 문서가 어떤 PDF/A 레벨이라도 준수하면true.PdfFormat–PdfA1b,PdfA2u등 정확한 버전을 나타내는 열거형.
Step 3 – Perform the Compliance Check
이제 플래그를 읽고, 해당되는 경우 구체적인 PDF/A 변형을 출력합니다.
if (root.FileType.IsPdfA)
{
// 문서가 준수함 – 정확한 버전을 보고한다.
Console.WriteLine($"✅ PDF/A compliant – version: {root.FileType.PdfFormat}");
}
else
{
// 문서가 PDF/A 요구 사항을 충족하지 않음.
Console.WriteLine("❌ The document is NOT PDF/A compliant.");
}
보이는 점:
- 단일 불리언(
IsPdfA)으로 즉시 통과/불통 결과를 얻을 수 있습니다. true인 경우PdfFormat이 정확한 적합 레벨을 제공하므로 로그, 데이터베이스 또는 감사 보고서에 저장할 수 있습니다.
Complete Working Example
세 단계를 하나로 합치면 복사‑붙여넣기 가능한 간결한 프로그램이 됩니다:
using System;
using GroupDocs.Metadata;
using GroupDocs.Metadata.Formats.Pdf;
class Program
{
static void Main(string[] args)
{
string pdfPath = "sample.pdf";
using (Metadata metadata = new Metadata(pdfPath))
{
var root = metadata.GetRootPackage<PdfRootPackage>();
if (root.FileType.IsPdfA)
{
Console.WriteLine($"✅ PDF/A compliant – version: {root.FileType.PdfFormat}");
}
else
{
Console.WriteLine("❌ The document is NOT PDF/A compliant.");
}
}
}
}
dotnet run으로 프로그램을 실행합니다. 적합한 파일에 대한 샘플 출력은 다음과 같습니다:
✅ PDF/A compliant – version: PdfA2u
비적합 파일의 경우:
❌ The document is NOT PDF/A compliant.
Real‑World Applications
1. 자동 보관 파이프라인 – 드롭‑폴더를 스캔하고 위 스니펫으로 각 PDF를 검증한 뒤, 적합한 파일만 장기 보관 계층으로 이동합니다.
2. 웹 포털 업로드 검증 – 동일한 로직을 ASP.NET Core 컨트롤러에 래핑(아래 선택 코드 스니펫 참고)하여 비‑PDF/A 업로드를 저장 전에 차단합니다.
3. 서버리스 적합성 검사 – Blob 생성 시 트리거되는 Azure Function으로 메서드를 배포하고, JSON 페이로드에 적합성 상태를 반환합니다.
// 최소 Azure Function 페이로드 (발췌)
var result = new
{
file = file.FileName,
isPdfA = root.FileType.IsPdfA,
format = root.FileType.IsPdfA ? root.FileType.PdfFormat.ToString() : null
};
Best Practices & Tips
- 경로를 먼저 검증 –
Path.GetFullPath를 사용하고 존재 여부를 확인한 뒤Metadata를 생성해FileNotFoundException을 방지합니다. - 라이브러리를 최신 상태로 유지 – 최신 릴리스는 형식 감지를 개선하고 엣지 케이스 버그를 수정합니다.
- 즉시 해제 – 여기서 보여준
using패턴은 네이티브 리소스가 적절히 해제되도록 보장합니다. - 예외 처리 – 생성자를
try/catch로 감싸고 손상된 PDF에 대해MetadataException을 로깅합니다. - 대량 배치 시 병렬화 –
Parallel.ForEach내부에서 파일당 별도Metadata인스턴스를 생성하면 됩니다. 인스턴스를 공유하지 않을 경우 API는 스레드‑안전합니다.
Troubleshooting Common Issues
문제: IsPdfA가 true인데도 root.FileType.PdfFormat이 null을 반환합니다.
- 해결책:
PdfFormat열거형이 완전히 채워진 GroupDocs.Metadata v23.6 이상을 사용하고 있는지 확인합니다. NuGet 패키지를 업데이트하면 보통 해결됩니다.
문제: 손상된 PDF에서 FileFormatException이 발생합니다.
- 해결책:
new Metadata(pdfPath)호출을try/catch로 감싸고 파일명을 로그에 기록한 뒤 배치 시 해당 파일을 건너뜁니다.
문제: 다중 기가바이트 PDF를 처리할 때 메모리 사용량이 높아집니다.
- 해결책:
Metadata를FileStream과enableStreaming플래그를true로 설정하여 스트리밍 모드로 생성합니다(예:new Metadata(stream, true)).