C# 压缩pdf文档时压缩档案无效

C# 压缩pdf文档时压缩档案无效,c#,C#,我有一些文档(pdf和html)作为字节数组。现在我必须创建这些文档的zip存档。压缩HTMLs的工作没有问题,但由于某种原因,pdf文档的zip存档都是无效的 我已经试着只保存没有拉链的PDF文件,它们工作得很好 以下是我创建拉链的代码: byte[]缓冲区; 使用(var memoryStream=new memoryStream()) { 使用(var zip=new ZipArchive(memoryStream,ZipArchiveMode.Create)) { var zipEntr

我有一些文档(pdf和html)作为字节数组。现在我必须创建这些文档的zip存档。压缩HTMLs的工作没有问题,但由于某种原因,pdf文档的zip存档都是无效的

我已经试着只保存没有拉链的PDF文件,它们工作得很好

以下是我创建拉链的代码:

byte[]缓冲区;
使用(var memoryStream=new memoryStream())
{
使用(var zip=new ZipArchive(memoryStream,ZipArchiveMode.Create))
{
var zipEntry=zip.CreateEntry(document.FileName);
使用(var binaryWriter=newbinarywriter(zipEntry.Open()))
{
binaryWriter.Write(document.Content);
}
}
buffer=memoryStream.GetBuffer();
}

正如前面指出的那样,
GetBuffer()
方法可能会返回额外的字节。要获取实际缓冲区,必须使用
ToArray()

如果要将字节保存到文件中,或以某种API形式返回字节,则可以使用流作为该操作的源

如果要保存到磁盘中的文件,请使用
Stream.CopyTo
传递新的
FileStream
。如果要在WebAPI中返回这些字节,请创建一个
StreamContent
并返回它


GetBuffer
将返回底层缓冲区的流,该缓冲区最终将包含未使用的字节
ToArray
将创建额外的不必要的
字节[]

为什么要将zip文件写入内存流而不是直接写入文件流?我认为您需要刷新writer,因为并非所有字节都已写入流。此外,缓冲区将只包含写入流的最后一个数据,缓冲区的大小始终为定义的常量。您不应该调用(请参阅备注部分)。@Nkosi nope,问题是他在刷新存档流之前复制了存档流,但我确实刷新了存档流。@orhtej2非常感谢。这就是问题所在。还有,为什么在这里使用BinaryWriter?这个想法是从哪里来的?有什么可能阻止您直接将
document.Content
写入由
zipEntry.Open()
提供的流,而无需绕道BinaryWriter?-1。“GetBuffer()方法总是返回一个大小为256字节的缓冲区。”这是完全错误的
MemoryStream.GetBuffer()
不会总是返回大小为256字节的缓冲区。(它只会返回一个缓冲区——嗯,那么我理解错了文档……但是为什么在使用GetBuffer而不是ToArray()时我的zip被破坏了呢?)?您不了解文档的哪一部分?MemoryStream.GetBuffer方法的文档在备注部分的开头告诉您可能存在此问题的原因。缓冲区可能只是大于写入MemoryStream的数据量。因此,无论您使用什么方法来处理/测试ZIP存档可能会被ZIP存档结束后可能出现的额外和多余的垃圾字节弄糊涂,并声明ZIP存档已损坏。
ToArray
只需创建并返回一个与写入MemoryStream的数据大小完全相同的数组,从而完全避免可能出现的添加问题al在ZIP存档数据结束后丢弃字节。好吧,很抱歉,这是一个漫长的工作日,我很累。现在我明白了。我更正了答案。请注意,在使用
Stream.CopyTo
将MemoryStream内容转储到另一个(文件)之前流,则需要将MemoryStream读/写位置重置回MemoryStream的开头(
MemoryStream.position=0
)。否则,将不会复制任何内容,因为MemoryStream的读/写位置位于并保持在写入数据之后。(避免CopyTo的另一个选项是简单地提供另一个选项。)(文件)直接流到ZipArchive)