diff --git a/SharpCompress/Archive/SevenZip/SevenZipArchive.cs b/SharpCompress/Archive/SevenZip/SevenZipArchive.cs
index 14792f67..3af441e0 100644
--- a/SharpCompress/Archive/SevenZip/SevenZipArchive.cs
+++ b/SharpCompress/Archive/SevenZip/SevenZipArchive.cs
@@ -236,7 +236,7 @@ namespace SharpCompress.Archive.SevenZip
protected override EntryStream GetEntryStream()
{
- return new EntryStream(new ReadOnlySubStream(currentStream, currentItem.Size));
+ return CreateEntryStream(new ReadOnlySubStream(currentStream, currentItem.Size));
}
}
}
diff --git a/SharpCompress/Common/EntryStream.cs b/SharpCompress/Common/EntryStream.cs
index 606bb160..a14bbbbb 100644
--- a/SharpCompress/Common/EntryStream.cs
+++ b/SharpCompress/Common/EntryStream.cs
@@ -26,12 +26,27 @@ namespace SharpCompress.Common
completed = true;
}
+ public bool Cancelled { get; private set; }
+
+ ///
+ /// Indicates that the remainder of the stream is not required.
+ /// On dispose, the entry will not be skipped, so it helps with efficiency.
+ /// The downside is that subsequent entries are not usable, as the compressed stream is not positioned at an entry boundary.
+ ///
+ public void Cancel()
+ {
+ if (!completed)
+ {
+ Cancelled = true;
+ stream.Close();
+ }
+ }
+
protected override void Dispose(bool disposing)
{
- if (!completed)
+ if (!(completed || Cancelled))
{
- throw new InvalidOperationException(
- "EntryStream has not been fully consumed. Read the entire stream or use SkipEntry.");
+ SkipEntry();
}
if (isDisposed)
{
diff --git a/SharpCompress/Reader/AbstractReader.cs b/SharpCompress/Reader/AbstractReader.cs
index 0c98e032..bd940ce8 100644
--- a/SharpCompress/Reader/AbstractReader.cs
+++ b/SharpCompress/Reader/AbstractReader.cs
@@ -77,6 +77,12 @@ namespace SharpCompress.Reader
{
return LoadStreamForReading(RequestInitialStream());
}
+
+ if (currentEntryStream != null && currentEntryStream.Cancelled)
+ {
+ throw new InvalidOperationException("EntryStream has not been fully consumed. Read the entire stream or use SkipEntry.");
+ }
+
if (!wroteCurrentEntry)
{
SkipEntry();
@@ -197,9 +203,19 @@ namespace SharpCompress.Reader
return stream;
}
+ private EntryStream currentEntryStream;
+
+ ///
+ /// Retains a reference to the entry stream, so we can check whether it completed later.
+ ///
+ protected EntryStream CreateEntryStream(Stream decompressed)
+ {
+ return currentEntryStream = new EntryStream(decompressed);
+ }
+
protected virtual EntryStream GetEntryStream()
{
- return new EntryStream(Entry.Parts.First().GetCompressedStream());
+ return CreateEntryStream(Entry.Parts.First().GetCompressedStream());
}
#endregion
diff --git a/SharpCompress/Reader/Rar/RarReader.cs b/SharpCompress/Reader/Rar/RarReader.cs
index 68ee8b2f..58a1be35 100644
--- a/SharpCompress/Reader/Rar/RarReader.cs
+++ b/SharpCompress/Reader/Rar/RarReader.cs
@@ -73,7 +73,7 @@ namespace SharpCompress.Reader.Rar
protected override EntryStream GetEntryStream()
{
- return new EntryStream(new RarStream(pack, Entry.FileHeader,
+ return CreateEntryStream(new RarStream(pack, Entry.FileHeader,
new MultiVolumeReadOnlyStream(
CreateFilePartEnumerableForCurrentEntry().Cast(), this)));
}