C#decode(解压缩)缩小PDF文件的数据

时间:2012-02-08 16:44:53

标签: c# deflate compression

我想在C#中解压缩一些DeflateCoded数据(PDF提取)。 不幸的是,我每次都遇到异常"解码时发现无效数据。"。 但数据是有效的。

private void Decompress()
{
    FileStream fs = new FileStream(@"S:\Temp\myFile.bin", FileMode.Open);

    //First two bytes are irrelevant
    fs.ReadByte();
    fs.ReadByte();

    DeflateStream d_Stream = new DeflateStream(fs, CompressionMode.Decompress);

    StreamToFile(d_Stream, @"S:\Temp\myFile1.txt", FileMode.OpenOrCreate);

    d_Stream.Close();
    fs.Close();
}

private static void StreamToFile(Stream inputStream, string outputFile, FileMode fileMode)
{
    if (inputStream == null)
        throw new ArgumentNullException("inputStream");

    if (String.IsNullOrEmpty(outputFile))
        throw new ArgumentException("Argument null or empty.", "outputFile");

    using (FileStream outputStream = new FileStream(outputFile, fileMode, FileAccess.Write))
    {
        int cnt = 0;
        const int LEN = 4096;
        byte[] buffer = new byte[LEN];

        while ((cnt = inputStream.Read(buffer, 0, LEN)) != 0)
            outputStream.Write(buffer, 0, cnt);
    }
}

有没有人有想法? 感谢。

4 个答案:

答案 0 :(得分:3)

我为测试数据添加了这个: -

private static void Compress()
{
  FileStream fs = new FileStream(@"C:\Temp\myFile.bin", FileMode.Create);

  DeflateStream d_Stream = new DeflateStream(fs, CompressionMode.Compress);
  for (byte n = 0; n < 255; n++)
    d_Stream.WriteByte(n);
  d_Stream.Close();
  fs.Close();
}

修改后的解压缩如下: -

private static void Decompress()
{
  FileStream fs = new FileStream(@"C:\Temp\myFile.bin", FileMode.Open);

  //First two bytes are irrelevant
  //      fs.ReadByte();
  //      fs.ReadByte();

  DeflateStream d_Stream = new DeflateStream(fs, CompressionMode.Decompress);

  StreamToFile(d_Stream, @"C:\Temp\myFile1.txt", FileMode.OpenOrCreate);

  d_Stream.Close();
  fs.Close();
}

像这样: -

static void Main(string[] args)
{
  Compress();
  Decompress();
}

没有错误。

我得出结论,前两个字节是相关的(显然它们与我的特定测试数据有关。)或 你的数据有问题。

我们可以提供一些测试数据吗?

(显然不要敏感)

答案 1 :(得分:2)

private static string decompress(byte[] input)
{
    byte[] cutinput = new byte[input.Length - 2];
    Array.Copy(input, 2, cutinput, 0, cutinput.Length);

    var stream = new MemoryStream();

    using (var compressStream = new MemoryStream(cutinput))
    using (var decompressor = new DeflateStream(compressStream, CompressionMode.Decompress))
        decompressor.CopyTo(stream);

    return Encoding.Default.GetString(stream.ToArray());
}

感谢user159335和user1011394让我走上正轨!只需将流的所有字节传递给上述函数的输入。确保bytecount与指定的长度相同。

答案 2 :(得分:2)

您需要做的就是使用GZip而不是Deflate。以下是我用于PDF文档中stream ... endstream部分内容的代码:

    col1
0   SUPER_280
1   AASD
2   AASD
3   SUPER_350
4   AASD
5   SUPER_150
6   AASD
7   AASD

答案 3 :(得分:0)

所有解决方案都不适用于PDF / A-3文档中的Deflate附件。一些研究表明,.NET DeflateStream不支持根据RFC1950带有头和尾的压缩流。

供参考的错误消息:使用不受支持的压缩方法压缩了存档条目。

解决方案是使用备用库SharpZipLib

这是一种简单的方法,可以为我成功地从PDF / A-3文件中解码Deflate附件:

public static string SZLDecompress(byte[] data) {
    var outputStream = new MemoryStream();
    using var compressedStream = new MemoryStream(data);
    using var inputStream = new InflaterInputStream(compressedStream);
    inputStream.CopyTo(outputStream);
    outputStream.Position = 0;
    return Encoding.Default.GetString(outputStream.ToArray());
}