}
File.Delete ("empty.zip");
}
+
+ class MyFakeStream : FileStream
+ {
+ public MyFakeStream (string path, FileMode mode) : base(path, mode) {}
+
+ /// <summary>
+ /// Simulate "CanSeek" is false, which is the case when you are retreiving data from web.
+ /// </summary>
+ public override bool CanSeek => false;
+ }
+
+ [Test]
+ public void ZipReadNonSeekableStream()
+ {
+ var stream = new MyFakeStream("test.nupkg", FileMode.Open);
+ using (var archive = new ZipArchive (stream, ZipArchiveMode.Read))
+ {
+ }
+ }
}
}
this.stream = stream;
mode = ZipArchiveMode.Read;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode)
this.stream = stream;
this.mode = mode;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode, bool leaveOpen)
this.stream = stream;
this.mode = mode;
leaveStreamOpen = leaveOpen;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding entryNameEncoding)
this.mode = mode;
leaveStreamOpen = leaveOpen;
this.entryNameEncoding = entryNameEncoding;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
- private void CreateZip(Stream stream, ZipArchiveMode mode)
+ private void CreateZip(ZipArchiveMode mode)
{
try {
if (mode != ZipArchiveMode.Read && mode != ZipArchiveMode.Create && mode != ZipArchiveMode.Update)
if (mode == ZipArchiveMode.Update && (!stream.CanRead || !stream.CanWrite || !stream.CanSeek))
throw new ArgumentException("Stream must support reading, writing and seeking for Update archive mode");
+ // If the stream is not seekable, then buffer it into memory (same behavior as .NET).
+ if (mode == ZipArchiveMode.Read && !stream.CanSeek)
+ {
+ var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+
+ if (!leaveStreamOpen)
+ stream.Dispose();
+
+ this.stream = memoryStream;
+ }
+
try {
zipFile = mode != ZipArchiveMode.Create && stream.Length != 0
? SharpCompress.Archive.Zip.ZipArchive.Open(stream)