C# ZipOutputStream 从输出流中获取无效文件
C# ZipOutputStream getting invalid files from output stream
我一直在使用 C# 的 SharpZip 库(版本 0.86.0)。我基本上是用它把一些文件打包成一个干净的 zip 文件。这是我的函数生成 zip 文件的字节数组的样子:
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
entry.Size = file.Item1.Length;
crc.Reset();
crc.Update(file.Item1);
entry.Crc = crc.Value;
zOutput.PutNextEntry(entry);
zOutput.Write(file.Item1, 0, file.Item1.Length);
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}
该函数适用于包含一项的文件。但是由于某种原因,当我有两个或更多时,当我转到 extract/open 时会出错。
PeaZip 说:
Archive is not readable
WinZip 说:
The compressed size stored in the local header for this file is not the same as the compressed size stored in the central header
但这是关键。 Windows 8 存档工具可以很好地处理文件。 WinZip 错误让我觉得我没有正确地将文件写入流。但我觉得很好。不知道该怎么做..
编辑
这是我对 codemonkeys 输入所做的更改。我看起来好多了,但我仍然遇到同样的错误
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
entry.Size = file.Item1.Length;
crc.Reset();
crc.Update(file.Item1);
entry.Crc = crc.Value;
zOutput.PutNextEntry(entry);
var memStreamCurrentfile = new MemoryStream(file.Item1);
StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}
想通了!看来我设置 Crc 和文件条目的大小是问题所在。我认为这将有助于定义这些。我想我错了。下面是最后的代码,供大家欣赏:
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
zOutput.PutNextEntry(entry);
var memStreamCurrentfile = new MemoryStream(file.Item1);
StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}
我一直在使用 C# 的 SharpZip 库(版本 0.86.0)。我基本上是用它把一些文件打包成一个干净的 zip 文件。这是我的函数生成 zip 文件的字节数组的样子:
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
entry.Size = file.Item1.Length;
crc.Reset();
crc.Update(file.Item1);
entry.Crc = crc.Value;
zOutput.PutNextEntry(entry);
zOutput.Write(file.Item1, 0, file.Item1.Length);
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}
该函数适用于包含一项的文件。但是由于某种原因,当我有两个或更多时,当我转到 extract/open 时会出错。
PeaZip 说:
Archive is not readable
WinZip 说:
The compressed size stored in the local header for this file is not the same as the compressed size stored in the central header
但这是关键。 Windows 8 存档工具可以很好地处理文件。 WinZip 错误让我觉得我没有正确地将文件写入流。但我觉得很好。不知道该怎么做..
编辑
这是我对 codemonkeys 输入所做的更改。我看起来好多了,但我仍然遇到同样的错误
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
entry.Size = file.Item1.Length;
crc.Reset();
crc.Update(file.Item1);
entry.Crc = crc.Value;
zOutput.PutNextEntry(entry);
var memStreamCurrentfile = new MemoryStream(file.Item1);
StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}
想通了!看来我设置 Crc 和文件条目的大小是问题所在。我认为这将有助于定义这些。我想我错了。下面是最后的代码,供大家欣赏:
public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
MemoryStream zipMemoryStream = new MemoryStream();
ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
zOutput.SetLevel(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach (var file in fileItemList)
{
ZipEntry entry = new ZipEntry(file.Item2);
entry.DateTime = DateTime.Now;
zOutput.PutNextEntry(entry);
var memStreamCurrentfile = new MemoryStream(file.Item1);
StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner = false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position = 0;
byte[] zipedFile = zipMemoryStream.ToArray();
return zipedFile;
}