C# 使用iText獲取PDF的trailer數據

文章目錄

    • C# 使用iText獲取PDF的trailer數據
      • iText 核心概念
      • C# 代碼示例
        • 步驟 1: 確保已安裝 iText
        • 步驟 2: C# 代碼
        • 程序運行效果
      • 解讀 Trailer 的輸出
      • 總結

C# 使用iText獲取PDF的trailer數據

開發程序debug的時候,看到了PDF有個trailer數據,挺有意思,于是考慮用代碼把它讀出來,那么就用到我們常用的iText框架了。

實際上,使用 iText 獲取 PDF 的 trailer 數據是一個稍微底層一些的操作,但完全可以實現。trailer 是 PDF 文件結構的核心部分,它告訴解析器如何找到文件的關鍵部分,比如交叉引用表 (xref)、文檔信息字典 (/Info) 和文檔根對象 (/Root)。

在 iText 中,這個操作被很好地封裝了。本文將詳細說明能從 trailer 中獲得什么信息。

iText 核心概念

  • 高級抽象 vs. 底層訪問: iText 提供了高級的類,如 PdfDocumentInfoPdfCatalog,來方便地訪問 trailer 指向的內容。例如,pdfDocument.GetDocumentInfo() 會自動找到 trailer 中的 /Info 條目并解析它。
  • 直接訪問: 同時,iText 也允許你直接獲取 trailer 本身,它是一個 PdfDictionary 對象。這對于需要檢查非標準字段或進行底層分析的程序員來說非常有用。

C# 代碼示例

這個示例將演示如何打開一個 PDF 文件,并同時使用高級方法和底層方法來檢查 trailer 相關的數據。

步驟 1: 確保已安裝 iText

請在你的項目中通過 NuGet 包管理器安裝 itext

Install-Package itext
步驟 2: C# 代碼
using System;
using System.IO;
using iText.Kernel.Pdf;public class PdfTrailerInspector
{public static void InspectPdfTrailer(string filePath){if (!File.Exists(filePath)){Console.WriteLine($"錯誤:文件不存在 '{filePath}'");return;}try{// 使用 PdfReader 和 PdfDocument 打開 PDF 文件using (var pdfReader = new PdfReader(filePath))using (var pdfDocument = new PdfDocument(pdfReader)){Console.WriteLine($"--- 正在分析文件: {Path.GetFileName(filePath)} ---");// --- 方法 1: 使用高級 API 訪問 Trailer 指向的內容 (推薦的常規做法) ---Console.WriteLine("\n=== 通過高級 API 獲取 Trailer 指向的信息 ===");// GetDocumentInfo() 會讀取 trailer 的 /Info 字典PdfDocumentInfo docInfo = pdfDocument.GetDocumentInfo();Console.WriteLine($"信息字典 (來自 /Info): Creator = {docInfo.GetCreator()}, Producer = {docInfo.GetProducer()}");// GetCatalog() 會讀取 trailer 的 /Root 字典,這是文檔的入口點PdfCatalog catalog = pdfDocument.GetCatalog();Console.WriteLine($"文檔目錄 (來自 /Root): 頁面模式 = {catalog.GetPageMode()}, 頁面布局 = {catalog.GetPageLayout()}");// --- 方法 2: 直接訪問和遍歷 Trailer 字典本身 (底層操作) ---Console.WriteLine("\n=== 直接訪問 Trailer 字典的原始鍵值對 ===");// 使用 GetTrailer() 直接獲取 Trailer 字典對象PdfDictionary trailer = pdfDocument.GetTrailer();if (trailer != null){// 遍歷 Trailer 字典中的所有條目foreach (var key in trailer.KeySet()){PdfObject value = trailer.Get(key); // 值 (可能是數字、引用等)Console.WriteLine($"鍵: {key}, 值: {value}, 值的類型: {value.GetType().Name}");}// 你也可以直接獲取特定的鍵Console.WriteLine("\n--- 單獨獲取 Trailer 中的關鍵值 ---");PdfObject size = trailer.Get(PdfName.Size);PdfObject root = trailer.Get(PdfName.Root);PdfObject info = trailer.Get(PdfName.Info);PdfObject id = trailer.Get(PdfName.ID);Console.WriteLine($"大小 (Size): {size}");Console.WriteLine($"根對象引用 (Root): {root}");Console.WriteLine($"信息字典引用 (Info): {info}");Console.WriteLine($"文件ID (ID): {id}");}else{Console.WriteLine("無法獲取 Trailer 字典。");}}}catch (Exception ex){Console.WriteLine($"讀取 PDF 時發生錯誤: {ex.Message}");}}public static void Main(string[] args){// 請將 "C:\\path\\to\\your\\document.pdf" 替換為你的 PDF 文件路徑string pdfPath = "C:\\path\\to\\your\\document.pdf"; InspectPdfTrailer(pdfPath);}
}
程序運行效果

效果

解讀 Trailer 的輸出

當你運行上面的代碼并查看“直接訪問 Trailer 字典”部分的輸出時,你會看到類似下面的內容:

鍵: /Size, 值: 25, 值的類型: PdfNumber
鍵: /Root, 值: 23 0 R, 值的類型: PdfIndirectReference
鍵: /Info, 值: 1 0 R, 值的類型: PdfIndirectReference
鍵: /ID, 值: [<0DDB5968...>, <F3C3B2A6...>], 值的類型: PdfArray

這里是對這些關鍵條目的解釋:

  • /Size: (類型: PdfNumber) 表示 PDF 文件中對象的總數(大約值)。
  • /Root: (類型: PdfIndirectReference) 這是一個間接引用,指向文檔的根對象(Catalog 字典)。23 0 R 的意思是“第 23 號對象,第 0 代”。iText 使用這個引用來找到文檔的所有頁面和其他核心內容。pdfDocument.GetCatalog() 就是幫你完成了這個查找過程。
  • /Info: (類型: PdfIndirectReference) 同樣是一個間接引用,指向文檔的信息字典(包含作者、標題等元數據)。1 0 R 指向第 1 號對象。pdfDocument.GetDocumentInfo() 會自動解析這個引用。
  • /ID: (類型: PdfArray) 這是一個包含兩個字符串的數組,用于唯一標識該 PDF 文件。第一個字符串在文件創建時生成,并且永不改變。第二個字符串在每次保存文件時都會更新。這對于追蹤文件的版本非常有用。
  • /Prev (可選): 如果文件是增量更新的,這個鍵會指向前一個版本的交叉引用表的位置。
  • /Encrypt (可選): 如果文件被加密,這個鍵會指向加密字典。

總結

  1. 常規需求: 如果我們只是想獲取作者、標題、頁面內容等信息,使用 iText 的高級 API(GetDocumentInfo(), GetCatalog(), GetPage() 等)就足夠了,它們在后臺為你處理了 trailer 的解析。
  2. 底層分析: 如果你需要檢查 trailer 的所有原始條目,或者查找可能存在的非標準字段,或者想驗證 PDF 結構,那么使用 pdfDocument.GetTrailer() 是最直接和強大的方法。

上面的代碼提供了兩種,我們可以根據具體需求選擇使用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92378.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92378.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92378.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

京東流量資產基于湖倉架構的落地實踐

在當今數字化商業浪潮中&#xff0c;數據無疑是企業的核心資產&#xff0c;而流量數據更是電商巨頭京東業務運轉的關鍵驅動力。它廣泛應用于搜索推薦、廣告投放等多個核心業務場景&#xff0c;直接影響著用戶體驗和商業效益。但隨著業務規模的不斷膨脹&#xff0c;傳統架構在處…

???????【Datawhale AI夏令營】多模態RAG財報問答挑戰賽:學習筆記與上分思考

一、 初識賽題——從迷茫到清晰剛看到賽題時&#xff0c;坦白說有些不知所措。“多模態”、“RAG”、“圖文混排PDF”&#xff0c;這些詞匯組合在一起&#xff0c;聽起來就像一個龐大而復雜的工程。但當我強迫自己靜下心來&#xff0c;從“終點”&#xff08;提交格式和評審規則…

數據挖掘2.6 Perceptron Modeling 感知器建模

Perceptron Modeling 感知器建模Linear Discriminants 線性判別式Loss Function 損失函數misclassification 誤分類0-1 Loss/Error function 0-1損失函數Hinge Loss Function 鉸鏈損失函數Optimization 優化算法Linear Discriminants 線性判別式 線性判別式公式 f(x;w)w1x(1)w…

使用qemu運行與GDB調試內核

目錄 一、前期準備 二、內核編譯 三、QEMU與GDB 1、QEMU調試參數 2、gdb vmlinux 一、前期準備 內核鏡像&#xff1a;bzimage gdb&#xff1a;x86_64 QEMU&#xff1a;qemu-system-x86_64 前置知識&#xff1a; &#xff08;1&#xff09;內核編譯 &#xff08;2&#x…

歐盟 Radio Equipment Directive (RED)

歐盟 Radio Equipment Directive (RED) ——從 2014/53/EU 原文到 2025-08-01 強制生效的網絡安全新規&#xff0c;一次看懂全部關鍵點。1. 法規身份與適用范圍要素內容指令全稱Directive 2014/53/EU on radio equipment取代指令1999/5/EC (R&TTE)適用產品所有“有意發射/接…

【FastExcel】解決ReadSheet在Map中獲取對象不準確問題(已提交PR并合并到開源社區)

解決問題&#xff1a;源碼ReadSheet在同一個Map中獲取對象不準確問題 PR&#xff1a;Fixed the issue where different ReadSheet objects could not get the correct value when comparing them. 一&#xff1a;問題場景 ReadSheet在同一個Map中獲取對象不準確(如Map<…

【網絡安全入門基礎教程】TCP/IP協議深入解析(非常詳細)零基礎入門到精通,收藏這一篇就夠了

前言 這是小編給粉絲盆友們整理的網絡安全入門到精通系列第三章計算機網絡中TCP/IP協議的解析&#xff0c;喜歡的朋友們&#xff0c;記得給大白點贊支持和收藏一下&#xff0c;關注我&#xff0c;學習黑客技術。TCP/IP協議包含了一系列的協議&#xff0c;也叫TCP/IP協議族&…

Latex中公式部分輸入正體的字母\mathrm{c}

Latex中公式部分輸入正體的字母\mathrm{c}“\mathrm{c}”如何在Word中輸入\mathrm{c}“\mathrm{c}” 在 LaTeX 中&#xff0c;“\mathrm{c}” 用于在數學模式中排版“c”這個字母為羅馬體&#xff08;正體&#xff09;。“\mathrm” 是羅馬字體命令&#xff0c;它告訴LaTeX以羅…

Document Picture-in-Picture API擁抱全新浮窗體驗[參考:window.open]

在前端開發中&#xff0c;我們經常會遇到這樣的需求&#xff1a;彈出一個浮動窗口來顯示一些實時信息、工具欄或視頻內容。過去我們會用 window.open()&#xff0c;后來越來越多的開發者傾向于使用 Modal。但現在&#xff0c;一個更現代的 API 出現了——Document Picture-in-P…

【指南版】網絡與信息安全崗位系列(三):安全運維工程師

一、安全運維工程師到底做什么&#xff1f;—— 用校園場景幫你理解簡單說&#xff0c;安全運維工程師就像 “網絡世界的安保隊長 系統管家”&#xff1a;既要實時監控網絡和系統的 “異常動靜”&#xff08;類似學校保安巡邏查隱患&#xff09;&#xff0c;又要負責日常的安全…

matlab——simulink學習(5向NXP庫中添加新模塊)

向NXP庫中添加新的函數模塊一、環境二、庫添加模塊1.打開文件夾2.創建文件3.添加S-Function三、瀏覽器添加模塊一、環境 Windows10、MATLAB R2022b、安裝NXP的S32K1XX系列工具包 二、庫添加模塊 1.打開文件夾 在文件系統中找到安裝工具包的位置&#xff0c;用文件資源管理器…

使用ProxySql實現MySQL的讀寫分離

ProxySQL簡介1、ProxySQL是一款開源的使用C編寫的MySQL集群代理中間件&#xff1b;2、用于在MySQL數據庫和客戶端之間進行負載均衡、查詢緩存、故障轉移和查詢分發&#xff1b;3、它可以作為中間層插入到應用程序和數據庫之間&#xff1b;4、特點是高效靈活&#xff0c;使用簡單…

WiFi 核心概念與實戰用例全解

&#x1f4d6; 推薦閱讀&#xff1a;《Yocto項目實戰教程:高效定制嵌入式Linux系統》 &#x1f3a5; 更多學習視頻請關注 B 站&#xff1a;嵌入式Jerry 1. WiFi基礎與協議 WiFi&#xff08;Wireless Fidelity&#xff09;是基于IEEE 802.11協議族的無線局域網&#xff08;WLAN…

面向遠程智能終端的超低延遲RTSP|RTMP視頻SDK架構與實踐指南

引言&#xff1a;遙操作時代&#xff0c;視覺鏈路已成“主控神經元” 從工業巡檢到應急救援&#xff0c;從城市安防到邊境監控&#xff0c;遠程操控正成為智能終端與人機協同的重要落點。而在這些場景中&#xff0c;“視覺”不再只是用來觀看的工具&#xff0c;而是貫穿感知、…

C++中的繼承:從基礎到復雜

目錄 前言 1. 繼承的基本概念 2. 繼承方式與訪問控制 3. 派生類與基類的對象轉換 4. 繼承中的作用域 5. 派生類的默認成員函數 6. 繼承中的特殊關系 6.1 繼承與友元 6.2 繼承與靜態成員 7. 復雜的菱形繼承問題 8. 繼承與組合的選擇 9. 常見面試題 總結 前言 繼承…

Eyevinn 徹底改變開源部署模式

該咨詢公司借助Akamai云平臺&#xff0c;為其創新的開源平臺和可持續收益分成模式提供強大支持。 "時間就是金錢&#xff0c;我們通過Akamai云平臺快速將開源云平臺投入生產。" ——Eyevinn Technology研發副總裁 Jonas Birm實現可持續視頻流媒體服務 自2013年以來&…

17day-人工智能-機器學習-分類算法-KNN

1. 什么是knn算法knn算法全名叫做k-近鄰算法&#xff08;K-Nearest Neighbors&#xff0c;簡稱KNN&#xff09;&#xff0c;看到名字是不是能想到是算距離的&#xff0c;第一個k是指超參數的意思&#xff0c;就是可以認為設置的意思&#xff0c;這里是指最近的k個樣本。2. 為什…

12-netty基礎-手寫rpc-編解碼-04

netty系列文章&#xff1a; 01-netty基礎-socket02-netty基礎-java四種IO模型03-netty基礎-多路復用select、poll、epoll04-netty基礎-Reactor三種模型05-netty基礎-ByteBuf數據結構06-netty基礎-編碼解碼07-netty基礎-自定義編解碼器08-netty基礎-自定義序列化和反序列化09-n…

解決 Windows 下的“幽靈文件”——記一次與帶空格的 .gitignore 文件的艱難斗爭

引言 你是否遇到過這樣的情況&#xff1a;一個文件明明躺在你的文件夾里&#xff0c;ls 或 dir 命令都能清楚地看到它&#xff0c;但無論你用什么方法嘗試刪除&#xff0c;系統都冷酷地告訴你“找不到文件”&#xff1f; 就在今天&#xff0c;我就遇到了這樣一個“幽靈”般的 .…