mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-08 18:16:30 +00:00
updates from review
This commit is contained in:
18
docs/API.md
18
docs/API.md
@@ -132,6 +132,15 @@ using (var archive = ZipArchive.OpenArchive("file.zip"))
|
||||
var firstEntry = archive.Entries.First();
|
||||
firstEntry.WriteToFile(@"C:\output\file.txt");
|
||||
|
||||
// Extract single entry to a stream with extraction options
|
||||
using (var outputStream = File.Create(@"C:\output\file.txt"))
|
||||
{
|
||||
firstEntry.WriteTo(
|
||||
outputStream,
|
||||
new ExtractionOptions { CheckCrc = false }
|
||||
);
|
||||
}
|
||||
|
||||
// Get entry stream
|
||||
using (var stream = entry.OpenEntryStream())
|
||||
{
|
||||
@@ -154,6 +163,15 @@ await using (var asyncArchive = await ZipArchive.OpenAsyncArchive("file.zip"))
|
||||
{
|
||||
await foreach (var entry in asyncArchive.EntriesAsync)
|
||||
{
|
||||
await using (var outputStream = File.Create(@"C:\output\" + entry.Key))
|
||||
{
|
||||
await entry.WriteToAsync(
|
||||
outputStream,
|
||||
new ExtractionOptions { CheckCrc = false },
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
using (var stream = await entry.OpenEntryStreamAsync(cancellationToken))
|
||||
{
|
||||
// ...
|
||||
|
||||
@@ -18,7 +18,19 @@ public static class IArchiveEntryExtensions
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
public void WriteTo(Stream streamToWriteTo, IProgress<ProgressReport>? progress = null) =>
|
||||
archiveEntry.WriteTo(streamToWriteTo, null, progress: progress);
|
||||
archiveEntry.WriteTo(streamToWriteTo, bufferSize: null, progress: progress);
|
||||
|
||||
/// <summary>
|
||||
/// Extract entry to the specified stream.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="options">Options for configuring extraction behavior.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
public void WriteTo(
|
||||
Stream streamToWriteTo,
|
||||
ExtractionOptions options,
|
||||
IProgress<ProgressReport>? progress = null
|
||||
) => archiveEntry.WriteTo(streamToWriteTo, options.BufferSize, options, progress);
|
||||
|
||||
private void WriteTo(
|
||||
Stream streamToWriteTo,
|
||||
@@ -50,8 +62,7 @@ public static class IArchiveEntryExtensions
|
||||
Stream streamToWriteTo,
|
||||
IProgress<ProgressReport>? progress = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
) =>
|
||||
await archiveEntry
|
||||
.WriteToAsync(
|
||||
streamToWriteTo,
|
||||
@@ -60,7 +71,29 @@ public static class IArchiveEntryExtensions
|
||||
cancellationToken: cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract entry to the specified stream asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="streamToWriteTo">The stream to write the entry content to.</param>
|
||||
/// <param name="options">Options for configuring extraction behavior.</param>
|
||||
/// <param name="progress">Optional progress reporter for tracking extraction progress.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
public async ValueTask WriteToAsync(
|
||||
Stream streamToWriteTo,
|
||||
ExtractionOptions options,
|
||||
IProgress<ProgressReport>? progress = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) =>
|
||||
await archiveEntry
|
||||
.WriteToAsync(
|
||||
streamToWriteTo,
|
||||
options.BufferSize,
|
||||
options,
|
||||
progress,
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
private async ValueTask WriteToAsync(
|
||||
Stream streamToWriteTo,
|
||||
|
||||
@@ -56,20 +56,7 @@ internal sealed class ChecksumValidationStream : Stream
|
||||
}
|
||||
#endif
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
var value = _stream.ReadByte();
|
||||
if (value == -1)
|
||||
{
|
||||
Validate();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateChecksum([(byte)value]);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
public override int ReadByte() => throw new NotSupportedException();
|
||||
|
||||
public override async Task<int> ReadAsync(
|
||||
byte[] buffer,
|
||||
|
||||
@@ -45,6 +45,34 @@ public class ZipCrcExtractionTests : ArchiveTests
|
||||
Assert.Equal(EntryData, File.ReadAllBytes(destination));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_Archive_WriteTo_Throws_On_Crc_Mismatch_When_Enabled()
|
||||
{
|
||||
using var zipStream = CreateZipWithInvalidCrc(useDataDescriptor: false);
|
||||
using var archive = ZipArchive.OpenArchive(zipStream);
|
||||
var entry = archive.Entries.Single(e => !e.IsDirectory);
|
||||
using var destination = new MemoryStream();
|
||||
|
||||
var exception = Assert.Throws<InvalidFormatException>(() =>
|
||||
entry.WriteTo(destination, new ExtractionOptions { CheckCrc = true })
|
||||
);
|
||||
|
||||
Assert.Contains(EntryName, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_Archive_WriteTo_Skips_Crc_Mismatch_When_Disabled()
|
||||
{
|
||||
using var zipStream = CreateZipWithInvalidCrc(useDataDescriptor: false);
|
||||
using var archive = ZipArchive.OpenArchive(zipStream);
|
||||
var entry = archive.Entries.Single(e => !e.IsDirectory);
|
||||
using var destination = new MemoryStream();
|
||||
|
||||
entry.WriteTo(destination, new ExtractionOptions { CheckCrc = false });
|
||||
|
||||
Assert.Equal(EntryData, destination.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Zip_Reader_WriteEntryToFile_Throws_On_Crc_Mismatch()
|
||||
{
|
||||
@@ -88,6 +116,34 @@ public class ZipCrcExtractionTests : ArchiveTests
|
||||
Assert.Contains(EntryName, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Zip_Archive_WriteToAsync_Throws_On_Crc_Mismatch_When_Enabled()
|
||||
{
|
||||
using var zipStream = CreateZipWithInvalidCrc(useDataDescriptor: false);
|
||||
using var archive = ZipArchive.OpenArchive(zipStream);
|
||||
var entry = archive.Entries.Single(e => !e.IsDirectory);
|
||||
await using var destination = new MemoryStream();
|
||||
|
||||
var exception = await Assert.ThrowsAsync<InvalidFormatException>(async () =>
|
||||
await entry.WriteToAsync(destination, new ExtractionOptions { CheckCrc = true })
|
||||
);
|
||||
|
||||
Assert.Contains(EntryName, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Zip_Archive_WriteToAsync_Skips_Crc_Mismatch_When_Disabled()
|
||||
{
|
||||
using var zipStream = CreateZipWithInvalidCrc(useDataDescriptor: false);
|
||||
using var archive = ZipArchive.OpenArchive(zipStream);
|
||||
var entry = archive.Entries.Single(e => !e.IsDirectory);
|
||||
await using var destination = new MemoryStream();
|
||||
|
||||
await entry.WriteToAsync(destination, new ExtractionOptions { CheckCrc = false });
|
||||
|
||||
Assert.Equal(EntryData, destination.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Zip_Reader_WriteEntryToFileAsync_Throws_On_Crc_Mismatch()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user