Yesterday I had a strange problem: When I wanted to pass a zip file as byte[]
and read it, i got an Ionic.Zip.ZipExpception
Cannot read that as a ZipFile
public string Import(byte[] file)
{
try
{
var stream = new MemoryStream(file);
if (ZipFile.IsZipFile(stream))
{
ImportArchive(stream);
} else {
...
}
...
}
private void ImportArchive(MemoryStream stream)
{
var zip = ZipFile.Read(stream); //--> ZipException thrown
...
}
Now if I pass the byte[]
as parameter and not the MemoryStream
, everything works fine:
public string Import(byte[] file)
{
try
{
if (ZipFile.IsZipFile(new MemoryStream(file), true))
{
ImportArchive(file);
} else {
...
}
...
}
private void ImportArchive(byte[] file)
{
var fileStream = new MemoryStream(file);
var zip = ZipFile.Read(fileStream); //--> no exception!
...
}
Where is the difference between those two versions? Why can't the first Version of the passed MemoryStream
be read?
ZipFile.IsZipFile
changes the stream position - it needs to read more than one byte of data. You need to "rewind" the stream before calling ImportArchive
:
stream.Position = 0;
This is not something that can be done automatically - when you pass some method a stream, it's usually assumed that you're pointing to the beginning of the relevant data. This allows you to have different data "packets" in one stream, and it means that you can use streams that aren't seekable.