我正在尝试编写一个解析 PDF 文件的程序。从我目前所读到的,PDF 文件是文本数据和二进制数据的组合。
例如,在 PDF 中,有以单词开头的“流”对象stream(newline)
,然后包含必要的二进制数据,然后以单词结尾endstream(newline)
这是一个例子:
677 0 obj
<</Length 2821
/Filter /FlateDecode>>
stream
xœ…ZÛnG}÷WLô’, Oú~AÙ 6—AGbKœ5Éf†¦õ™ù£=M™dŸÖX›‡ÄÏô¥êTÕ©j¸yLœ“·¡5J»æfõæÇ_T#M+ðOssÿ懫÷ëë57ÿ}óï›7nÞH[c¼£o~Ø»©Oûñúª„FÝ-yùÆýöv“VP9Ù¯ª5çu*1!´R‡j±iجú48}k…¶ŒûeìvwC?•71B´2hÁÈ~WBpYeUµØôØÏåÑŒµ¦Zh¸/!Þ´ÿbȺßNis_Ê‹¯1²u'ÜÕɼmiÞ³óþp†ÞtŸRs×éúª™º~Õ¼»-.Þ\ͧ_¾[\E„VœWùã¾9¬»ù]³JÝØüÖ6«ïMãí¦{:-û¡ë§´MÝþËu³î6÷M¿›‡/ý]7§U»°¾‹²U—S’o3§œ”A›4ÏäZi=h"
Ãëþn]E¨V™(U‘IùÖŽ0wÃ~d2)£¡w;ö»‡©äœÒv±:ÿ<”ìϨÍk§ÒÎã'_üaøœÆÝPËhÑ*ªã3áLh«OÞ•q?Œó˜¦òvÙ@ÇX½ŸXë@ó"6·iî·ijº]3Œ«´L_¯^˜þ;ø¶yjºÍ¡{š–ñFtÿyhvÃü¼üÔôÓ´OÍý8l˜¶Ùö»~‡¦w‹!n.Œÿ;!Fö»Õ°¿ƒ7O?5·ûùŸÅï„/˜ü~Wf2©Tk£Ê¡D<m”Ùò%ˆè"½k~® ë4¥n…õ–Qç[‘m«•1Œ\•[ªèZc£bŒ@DW4¦²âf—÷ëvUzU^ÅW(1pC1&/ÔÍû‘k2åK$QÞ
äØ(Íkžˆj£¸õÂy‘!Öë‚š¦qÝ=–V…)àHïø4ìÉ“fµŠ1]NFßjªuÆþa=—©Ti‹_fØï ù·Ü j¯ÉW[ƒ¤Dèïg
\m\®–Õ’Xð©ùØJ!"ƒæy!Ny †Â0ð°NÄPÛi_3š¶…áÌkF;»ÒºK>˜úy†7©¶À™ZhÆÝ&$ºTÅ$2‹aXGŽeœ°ŒxR2µQ8Ï ¹ƒà)}£ŒUÃ~üÅðšÓœÞvoóJgðÉ™úSÖl‡~.K¢ÖÁã·/§Q.¬s‘÷(‡»Õ?ï×ßQÌzœ]W†ÿXÑÀj©j“—nÁZtå°€ê\mºrÊc7¾]âꂸd¶‰VhíeÐIUýT"] 2F~$À˜9OtzÊT©dÈ2Ä1¬'ʸ51VÊÛÈ0
¹ìÛÇ<mQç«}kJíA·^Cé&íº¢––UºÚŒ#‹’c=c¨¼ÁÐ
ªÚmÚ?>¦‘ôwÖÁ™j)ª§·SVTÛÍ\OMÈB>ÊoÉ„LïXm5=¦îÓ“ 犲ÜtÍý>—£,žWý®Û,ê‹Ð?—”«ÿ¤¹JBÀ8í©–h4KÈ1yìHŠIga²œƒJPˆTMBîÐ"ƒ²Í(ÁÙB Z*Ë}jÌ4ì–£¡ÒŸRÎf¡8 ËîÌÔÐ*zÆŒ Öå¶+÷"¾²) $ƒZ(¤ª,Z¥(\Ř¯-cyt+Á²¶ ýNÜ0!^
Ò©«\äƒñªÐ©¥ÍæBxuì«Ð1MÍéëÉ*-ꃴwQ¨¿¦ãg«´ÝcZ-vqFÇB›â‹¾8ŒÃîá:+âÝò6Puæþ:²¢ ô ‰®¤¬ÜÂA`ZgRW4¿R=>{™?áJvº-Q×å‡ó”ŠÐ,ê“0SJe²×(e‰šAµD²2<ƒnÓ]·'1n Y<Šã`tÖ±¨üèP-£hC“S¬AÕã£çnjÍÚæLJa/¤L_汎‰ŠTœD4(MhwHŸÓdÞ¹„`W*Iˆ(BÁ m—›uR«?G(vÂ}¤ˆoTu$Ú-d%XŸº¨¹Öæø%Ðã0M=„å.êr9Â’qÕ©"!óP—r zHëcoC˜‰„œ#„÷ÕÁO‰aÁÓ…ìœT¸ÈK´?ZC2†CNÇPºÂäüP¢‚D`¢s 3á2yVp”¢zÉæ1A«¾&‡ú°ŒADSÉ*V¨W a(QÇnt´(^½r=#sÛQ[ ê]uÓðliÀ_\>¾²Yî[…Õ•-™(gÿgÂœd¹ÍßÁÜ
Dʺß.–!0¼T„¿òñÞ5ó·é¹24ÏÍй½kr@4È•Û©»œÁPxÆÕòòº˜g^ý Ø@<‘‚7†q[j†¤ËÁ”‰Ë˜1mÊ W(Ðp‚a]¹›½ÁLÅõãa¿éÆ~~j)k {mý‰‰óë<ª!L)-“¬-1¯‡=ºwÊ*ÐJžÏÆYÄÌš†
ñDIEäddÈj?(g9ç+3°|Šh=¬¯ýÒ}Zê°µ*fÑy–w;¥ñs7÷î9N_Á§ØÒôÛÇaœ»Ý¼LQΩÿ ¦RÊÜ¡¢ÈèñåÄÅç–IjÆUè_´(‘1œ”mÔÎ2æ8q¡'Œ,€µ·Õ᧹Ûf~®êì¤cuƒ‹TnÉÑÐ!T·¨†âÆ"•! 1(Ϫ¾Ÿ*Oc
ÃŽóÐWæW”åN3{ Ý#¦î·¤þX«4qœÍ%dkŒh} Ã…¨Fá(.&r0äyÐK1•¼¯®V•tåp꜅ùD¨UŸy¶¢PÕÀB‚Uó«ã$_[kÇ“|ü…~ÅÞ:äÒªëq#ód\Ô>yÙHç¤cå곀׶òȘР—Úü"¦_x…my¦’燤€Ïýfqb®lñ,põ±ÚfÕ‚^.0¦
h¸XgyG˜uGƒw¨[pN0&¿T¥²$)ˆ˜‡-BJ1d»ç'&„¦³º:4±W9„xN°áW¨˜cIVg~Ù)Z…ÜWW‡>"þY§-Oç"®øâüTð‹‹²:}Õùçy»ñõùéliø¦tñˆóõU07»ý=„Éôü<±Âÿ|:—‰»´X'rn¾$E½ S##CèC*(\¡=C¨ÌJÔP‹ÁŠåÒç¬b&hÆFl;Ö,yêcXÚå_°ÎU—‚¶Û·Äô°1ãhˆî:U[ð¶ŸÖÃ# 4˜6ÆÕ½úo¹…ö_˜\æYëð‡Ü±wÛªˆ…£Ô„ÔlUí0˜ˆ2\DÈ-qå²´[z;W¢xØK_îöSž¿/Ž>d(ßò~&&A¢÷7ŒaßIÅ
aò,8Ñù3W|Îä„[ž£)Èa¡Á<ÂÖ
=ŒTÊ2ˆt)Œàp6F¬;.xÇq‘¯ìph§½Çœ®ÄÇC˜¯£6Ö+(E&fy7t•Ã%ú¸P‡‰6ÿX;èã!ŽO7çE¶MwNÌÃ6r4Ü&œÙ¨És¯§CžØ,&&iËçÀ¿‡}s@l=ÖëžÔî›™âÆ¡ì$/Gì‚“Ñ=1¨NTδ¨Õfµ"†F™¦´Û°ßÐÛ•Îi!û¹Dñ1ª,:gñb³±â¦·¼zîæѤ@2Š
UÎSZ™ÈçG©Ÿˆ|Ø0@Ìó©ÿmŸ<0(ŒâÁ•ÈIJrÊ&u¿6ä.-V^yñ x枢‡Ã¯QA³"ByÅ<&hÑ–˜çÄ
ã¨KbuþôÁÿ ŒÃï
endstream
(注:“流”字前还有一些头信息,告诉你二进制数据有多长等)
我一直在做的是使用 aStreamReader
来读取文本数据,然后我想切换并只读取二进制数据。像这样的东西:
using (FileStream fs = new FileStream(myFile, FileMode.Open))
{
fs.Seek(250205, SeekOrigin.Begin); // This jumps to the start of the data above
using (StreamReader sr = new StreamReader(fs))
{
String line = "";
while ((line = sr.ReadLine()) != "stream"); // This skips to the end of "stream"
// I want this to read the 2821 bytes AFTER stream
byte[] buffer = new byte[2821];
fs.Read(buffer, 0, buffer.Length);
}
}
当我运行它时,buffer
不包含“流”之后的 2821 个字节。相反,它包含原始Seek()
位置之后 1024 字节的数据。
换句话说:我Seeked
到了 250205 的位置。然后,我读了几行(共 57 个字节)。但我buffer
从位置 251229(而不是 250262)开始。
我怎样才能从离开的FileStream
地方开始阅读?StreamReader
(我这样做的主要原因是因为FileStream
没有ReadLine()
方法,StreamReader
也没有byte[] = Read()
方法。)