C#解码(解压缩)PDF文件的泄气数据
我想用C#解压一些DeflateCoded数据(PDF提取)。 不幸的是,每次异常“在解码时发现无效数据”时,我都会收到。 但这些数据是有效的C#解码(解压缩)PDF文件的泄气数据,c#,deflate,compression,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();
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);
}
}
有人有什么想法吗?
谢谢。我为测试数据添加了以下内容:-
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();
}
没有错误
我得出结论,要么前两个字节相关(显然它们与我的特定测试数据相关),要么
您的数据有问题
我们可以用一些你的测试数据吗
(如果是敏感的,显然不需要)
感谢用户159335和用户1011394让我走上正轨!只需将流的所有字节传递给上述函数的输入。确保字节数与指定的长度相同。您需要做的就是使用GZip而不是Deflate。以下是我在PDF文档中用于stream…endstream部分内容的代码:
using System.IO.Compression;
public void DecompressStreamData(byte[] data)
{
int start = 0;
while ((this.data[start] == 0x0a) | (this.data[start] == 0x0d)) start++; // skip trailling cr, lf
byte[] tempdata = new byte[this.data.Length - start];
Array.Copy(data, start, tempdata, 0, data.Length - start);
MemoryStream msInput = new MemoryStream(tempdata);
MemoryStream msOutput = new MemoryStream();
try
{
GZipStream decomp = new GZipStream(msInput, CompressionMode.Decompress);
decomp.CopyTo(msOutput);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
对于PDF/a-3文档中的Deflate附件,没有一个解决方案对我有效。一些研究表明,根据RFC1950,.NET
DeflateStream
不支持带有标头和尾部的压缩流
错误消息供参考:存档项是使用不支持的压缩方法压缩的
解决方案是使用另一个库
下面是一个简单的方法,它成功地为我解码了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());
}
为什么前两个字节不相关?流解码器使用RFC1951。与deflatestream结合使用时,前两个字节是不相关的。如果流解码器使用的是RC1950,那么我也必须使用第一个字节。你做了什么来证明错误是错误的,并且数据实际上是有效的。
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());
}