.net DeflateStream 无法解码 PDF 流对象内容

.net DeflateStream fails to decode a PDF stream object content

提问人:Alex 75 提问时间:11/16/2023 最后编辑:Alex 75 更新时间:11/16/2023 访问量:15

问:

我使用 Word 2019 的导出功能创建了一个 PDF。

我正在将 PDF 解析为文本,并捕获对象的内容:

4 0 obj
<</Filter/FlateDecode/Length 344>>
stream
xœµRMKA½/ÌÈqWè˜dçÊBK?Ä‹hăØu)Ô•¶þL»[¨¶=¨íÂlHæ%yy™¥JPãæÁ ØhuÎéȰ*UòxµJúS•\Øëè`ú¦’
À³F6àM®YnÞ7žBµ–ÚP5.µîX%O]Dg
²]$;((н‚œX7j|‡y÷ƒÏ¡`Ü‹ïòlo‹ßÏÛàˆÚø.Ÿ° /¶oÛ¸ý–GÞÜÖ}†é­J†2ö½J–¿“‰È”£ÕLû2mÅi$I!ûO¿ˆ4š£ka{þ~dO<ƶŸ¦` ¥N”¿
VÕ±èÖÑMù2›×YǤdyzW—g§HV2þÎðb;rÞkov4šg&]­?!ëpº˜‹(µœRŸëx’ÆåÆ–uP8è7)_?²ŽÝ;“yæ"s³Ót’ǹ¿ ¹ÿy
endstream
endobj

我想解码 FlateEncoded 流,所以我写了这个函数:

let decodeFlateDecodeStream(encodedStream: string) =
    // Convert the encoded stream from a string to a byte array.
    let encodedBytes = Encoding.UTF8.GetBytes(encodedStream)

    // Create a MemoryStream from the byte array.
    use inputStream = new MemoryStream(encodedBytes)

    // Create a MemoryStream to store the decompressed data.
    use outputStream = new MemoryStream()

    // Create a DeflateStream to decompress the input stream.
    use deflateStream = new DeflateStream(inputStream, CompressionMode.Decompress)

    // Copy the decompressed data to the output stream.
    deflateStream.CopyTo(outputStream)

    // Convert the decompressed stream to a string (assuming it contains text).
    Encoding.UTF8.GetString(outputStream.ToArray())

当我传递流内容(“xœμRMK.....¹¿ ¹ÿy“),以字符串形式读取到它失败的函数,并出现以下错误:deflateStream.CopyTo(outputStream)

System.IO.InvalidDataException:使用不受支持的压缩方法压缩存档条目。

PDF 文档说它是 RFC 1951 Flate 压缩。
是 .net DeflateStream 没有能力做到这一点,还是我没有做正确的事情?

我发现 10 年前的帖子说 DeflateStream 无法正常工作,并建议使用第三方库。 DotZipLib 太旧了。我认为它或我发现的另一个与 .net 7 不兼容。 我相信我可以使用 .net 以及它已经提供的功能。 我试图跳过前 2 个字节,因为一些帖子声称编码数据中添加了 2 个字节头,以使其与 RFC 1950 兼容(我在 PDF 参考中没有找到这种声称的兼容性,它说 Flate 正在使用 RFC 1951)。 还是不行。

[更新]
我相信错误出在 PDF 本身的初始解析中。
我将其作为文本阅读: 然后连接“strem”和“endstream”标记之间的行。 我意识到由于逐行阅读,我丢失了 3 个“换行符”。 我在连接的文本行之间添加了一个额外的“/n”字符,但生成的编码字节数组仍然只有长 334 而不是 344 。
let lines = File.ReadAllLines pdfFile

我想我必须将 PDF 作为二进制文件阅读......以避免 UTF8 重新编码问题,如评论中所示?

.NET PDF 放气 deflatestream

评论

3赞 Charlieface 11/16/2023
您可能遇到一些 UTF8 重新编码问题:您有一个变量,但为什么它是一个字符串?为什么不首先将其保留为字节呢?encodedStream: string
2赞 mkl 11/16/2023
事实上,通过将压缩数据作为 utf-8 编码的字符串处理,您会损坏它。
0赞 K J 11/20/2023
ASCII 和 ASCII 之间的单行二进制切片必须通过二进制方式(如字节流)提取。不能有任何字符串化的暗示,它不会被编码为除 deflate 编码之外的任何东西(除非它有 2 个过滤器,但你的过滤器有一个)。要查看这些工作文本内容,有许多命令行pdf解压缩器(这是每个PDF阅读器应用程序都应该做的,转换为ASCII编码的文本标签,标志和说明)streamendstream

答: 暂无答案