0

我正在尝试从此文件中的 PDF 对象解压缩流:

 4 0 obj
<< 
/Filter /FlateDecode
/Length 64
>>
stream
xœs
QÐw34V02UIS0´0P030PIQÐpÉÏKIUH-.ITH.-*Ê··×TÉRp
á T‰
Ê
endstream
endobj

我将这个流复制粘贴到一个名为Stream.file

xœs
QÐw34V02UIS0´0P030PIQÐpÉÏKIUH-.ITH.-*Ê··×TÉRp
á T‰
Ê

此流应转换为:Donde esta curro??. 将该流添加到Stream.fileC# 控制台应用程序中的 a 中。

using System.IO;
using System.IO.Compression;

namespace Filters
{
    public static class FiltersLoader
    {
        public static void Parse()
        {
            var bytes = File.ReadAllBytes("Stream.file");
            var originalFileStream = new MemoryStream(bytes);

            using (var decompressedFileStream = new MemoryStream())
            using (var decompressionStream = new DeflateStream(originalFileStream, CompressionMode.Decompress))
            {
                decompressionStream.CopyTo(decompressedFileStream);
            }    
        }
    }
}

但是,在尝试复制它时会产生异常:

The archive entry was compressed using an unsupported compression method.

如果可能的话,我想如何用.net 代码解码这个流。

谢谢。

4

1 回答 1

4

主要问题是DeflateStream该类可以解码裸 FLATE 压缩流(根据RFC 1951 ),但具有FlateDecode过滤器的 PDF 流的内容实际上以包装FLATE 压缩数据的 ZLIB 压缩数据格式(根据RFC 1950)呈现。

要解决此问题,只需删除两字节 ZLIB 标头即可。

在您的第一个示例文档中,另一个问题变得很清楚:该文档已加密,因此在 FLATE 解码之前必须解密其中的流内容。

###Drop ZLIB 标头以获取 FLATE 编码数据

该类DeflateStream可以解码裸 FLATE 压缩流(根据RFC 1951 ),但使用FlateDecode过滤器的 PDF 流的内容实际上以包装FLATE 压缩数据的 ZLIB 压缩数据格式(根据RFC 1950)呈现。

幸运的是,跳转到其中的 FLATE 编码数据非常容易,只需删除前两个字节。(严格来说,它们和 FLATE 编码数据之间可能有一个字典标识符,但这似乎很少使用。)

如果是您的代码:

var bytes = File.ReadAllBytes("Stream.file");
var originalFileStream = new MemoryStream(bytes);

originalFileStream.ReadByte();
originalFileStream.ReadByte();

using (var decompressedFileStream = new MemoryStream())
using (var decompressionStream = new DeflateStream(originalFileStream, CompressionMode.Decompress))
{
    decompressionStream.CopyTo(decompressedFileStream);
}   

###如果是加密的PDF,请先解密

您的第一个示例文件pdf-test.pdf已加密,如预告片中存在Encrypt条目所示:

trailer
<</Size 37/Encrypt 38 0 R>>
startxref
116
%%EOF

因此,在解压缩流内容之前,您必须对其进行解密。

于 2019-10-02T10:08:57.723 回答