mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-24 07:54:39 +00:00
Skip entry stream on dispose
Until now the caller had to completely consume each entry stream, or call SkipEntry(), before disposing the stream. If not, exception was thrown: "EntryStream has not been fully consumed". Hugely inconvenient; a user-thrown exception inside a "using (EntryStream)" block would be discarded. Now automatically skips the entry on dispose. Added method EntryStream.Cancel(). Call this if entry stream is unfinished, and no further entries are required. Helps with efficiency, as it avoids reading data that is not needed.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,27 @@ namespace SharpCompress.Common
|
||||
completed = true;
|
||||
}
|
||||
|
||||
public bool Cancelled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Retains a reference to the entry stream, so we can check whether it completed later.
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
@@ -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<RarFilePart>(), this)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user