mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-11 05:24:56 +00:00
273 lines
9.0 KiB
C#
273 lines
9.0 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using SharpCompress.Archives;
|
|
using SharpCompress.Archives.GZip;
|
|
using SharpCompress.Archives.Zip;
|
|
using SharpCompress.Common;
|
|
using SharpCompress.Compressors;
|
|
using SharpCompress.Compressors.Deflate;
|
|
using SharpCompress.Readers;
|
|
using SharpCompress.Test.Mocks;
|
|
using SharpCompress.Writers;
|
|
using Xunit;
|
|
|
|
namespace SharpCompress.Test.GZip;
|
|
|
|
public class AsyncTests : TestBase
|
|
{
|
|
[Fact]
|
|
public async ValueTask Reader_Async_Extract_All()
|
|
{
|
|
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
#if NETFRAMEWORK
|
|
using var stream = File.OpenRead(testArchive);
|
|
#else
|
|
await using var stream = File.OpenRead(testArchive);
|
|
#endif
|
|
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
|
|
|
|
await reader.WriteAllToDirectoryAsync(SCRATCH_FILES_PATH);
|
|
|
|
// Just verify some files were extracted
|
|
var extractedFiles = Directory.GetFiles(
|
|
SCRATCH_FILES_PATH,
|
|
"*",
|
|
SearchOption.AllDirectories
|
|
);
|
|
Assert.True(extractedFiles.Length > 0, "No files were extracted");
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask Reader_Async_Extract_Single_Entry()
|
|
{
|
|
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
#if NETFRAMEWORK
|
|
using var stream = File.OpenRead(testArchive);
|
|
#else
|
|
await using var stream = File.OpenRead(testArchive);
|
|
#endif
|
|
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
|
|
|
|
while (await reader.MoveToNextEntryAsync())
|
|
{
|
|
if (!reader.Entry.IsDirectory)
|
|
{
|
|
var outputPath = Path.Combine(SCRATCH_FILES_PATH, reader.Entry.Key!);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
|
|
#if NETFRAMEWORK
|
|
using var outputStream = File.Create(outputPath);
|
|
#else
|
|
await using var outputStream = File.Create(outputPath);
|
|
#endif
|
|
await reader.WriteEntryToAsync(outputStream);
|
|
break; // Just test one entry
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask Archive_Entry_Async_Open_Stream()
|
|
{
|
|
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
await using var archive = GZipArchive.OpenAsyncArchive(
|
|
new AsyncOnlyStream(File.OpenRead(testArchive))
|
|
);
|
|
|
|
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory).Take(1))
|
|
{
|
|
#if NETFRAMEWORK
|
|
using var entryStream = await entry.OpenEntryStreamAsync();
|
|
#else
|
|
await using var entryStream = await entry.OpenEntryStreamAsync();
|
|
#endif
|
|
Assert.NotNull(entryStream);
|
|
Assert.True(entryStream.CanRead);
|
|
|
|
// Read some data to verify it works
|
|
var buffer = new byte[1024];
|
|
var read = await entryStream.ReadAsync(buffer, 0, buffer.Length);
|
|
Assert.True(read > 0);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask Writer_Async_Write_Single_File()
|
|
{
|
|
var outputPath = Path.Combine(SCRATCH_FILES_PATH, "async_test.zip");
|
|
|
|
#if NETFRAMEWORK
|
|
using (var stream = File.Create(outputPath))
|
|
#else
|
|
await using (var stream = File.Create(outputPath))
|
|
#endif
|
|
using (
|
|
var writer = WriterFactory.OpenAsyncWriter(
|
|
new AsyncOnlyStream(stream),
|
|
ArchiveType.Zip,
|
|
new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = false }
|
|
)
|
|
)
|
|
{
|
|
var testFile = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
|
|
#if NETFRAMEWORK
|
|
using var fileStream = File.OpenRead(testFile);
|
|
#else
|
|
await using var fileStream = File.OpenRead(testFile);
|
|
#endif
|
|
await writer.WriteAsync("test_entry.bin", fileStream, new DateTime(2023, 1, 1));
|
|
}
|
|
|
|
// Verify the archive was created and contains the entry
|
|
Assert.True(File.Exists(outputPath));
|
|
await using var archive = ZipArchive.OpenAsyncArchive(outputPath);
|
|
Assert.Single(await archive.EntriesAsync.Where(e => !e.IsDirectory).ToListAsync());
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask Async_With_Cancellation_Token()
|
|
{
|
|
using var cts = new CancellationTokenSource();
|
|
cts.CancelAfter(10000); // 10 seconds should be plenty
|
|
|
|
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
#if NETFRAMEWORK
|
|
using var stream = File.OpenRead(testArchive);
|
|
#else
|
|
await using var stream = File.OpenRead(testArchive);
|
|
#endif
|
|
await using var reader = await ReaderFactory.OpenAsyncReader(
|
|
new AsyncOnlyStream(stream),
|
|
cancellationToken: cts.Token
|
|
);
|
|
|
|
await reader.WriteAllToDirectoryAsync(SCRATCH_FILES_PATH, cts.Token);
|
|
|
|
// Just verify some files were extracted
|
|
var extractedFiles = Directory.GetFiles(
|
|
SCRATCH_FILES_PATH,
|
|
"*",
|
|
SearchOption.AllDirectories
|
|
);
|
|
Assert.True(extractedFiles.Length > 0, "No files were extracted");
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask Stream_Extensions_Async()
|
|
{
|
|
var testFile = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
var outputPath = Path.Combine(SCRATCH_FILES_PATH, "async_copy.bin");
|
|
#if NETFRAMEWORK
|
|
using var inputStream = File.OpenRead(testFile);
|
|
using var outputStream = File.Create(outputPath);
|
|
#else
|
|
await using var inputStream = File.OpenRead(testFile);
|
|
await using var outputStream = File.Create(outputPath);
|
|
#endif
|
|
|
|
// Test the async extension method
|
|
var buffer = new byte[8192];
|
|
int bytesRead;
|
|
while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
|
{
|
|
await outputStream.WriteAsync(buffer, 0, bytesRead);
|
|
}
|
|
|
|
Assert.True(File.Exists(outputPath));
|
|
Assert.True(new FileInfo(outputPath).Length > 0);
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask EntryStream_ReadAsync_Works()
|
|
{
|
|
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
|
|
#if NETFRAMEWORK
|
|
using var stream = File.OpenRead(testArchive);
|
|
#else
|
|
await using var stream = File.OpenRead(testArchive);
|
|
#endif
|
|
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
|
|
|
|
while (await reader.MoveToNextEntryAsync())
|
|
{
|
|
if (!reader.Entry.IsDirectory)
|
|
{
|
|
#if NETFRAMEWORK
|
|
using var entryStream = await reader.OpenEntryStreamAsync();
|
|
#else
|
|
await using var entryStream = await reader.OpenEntryStreamAsync();
|
|
#endif
|
|
var buffer = new byte[4096];
|
|
var totalRead = 0;
|
|
int bytesRead;
|
|
|
|
// Test ReadAsync on EntryStream
|
|
while ((bytesRead = await entryStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
|
{
|
|
totalRead += bytesRead;
|
|
}
|
|
|
|
Assert.True(totalRead > 0, "Should have read some data from entry stream");
|
|
break; // Test just one entry
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async ValueTask CompressionStream_Async_ReadWrite()
|
|
{
|
|
var testData = new byte[1024];
|
|
new Random(42).NextBytes(testData);
|
|
|
|
var compressedPath = Path.Combine(SCRATCH_FILES_PATH, "async_compressed.gz");
|
|
|
|
// Test async write with GZipStream
|
|
#if NETFRAMEWORK
|
|
using (var fileStream = File.Create(compressedPath))
|
|
using (var gzipStream = new GZipStream(fileStream, CompressionMode.Compress))
|
|
#else
|
|
await using (var fileStream = File.Create(compressedPath))
|
|
await using (var gzipStream = new GZipStream(fileStream, CompressionMode.Compress))
|
|
#endif
|
|
{
|
|
await gzipStream.WriteAsync(testData, 0, testData.Length);
|
|
await gzipStream.FlushAsync();
|
|
}
|
|
|
|
Assert.True(File.Exists(compressedPath));
|
|
Assert.True(new FileInfo(compressedPath).Length > 0);
|
|
#if NETFRAMEWORK
|
|
using (var fileStream = File.OpenRead(compressedPath))
|
|
using (var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress))
|
|
#else
|
|
// Test async read with GZipStream
|
|
await using (var fileStream = File.OpenRead(compressedPath))
|
|
await using (var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress))
|
|
#endif
|
|
{
|
|
var decompressed = new byte[testData.Length];
|
|
var totalRead = 0;
|
|
int bytesRead;
|
|
while (
|
|
totalRead < decompressed.Length
|
|
&& (
|
|
bytesRead = await gzipStream.ReadAsync(
|
|
decompressed,
|
|
totalRead,
|
|
decompressed.Length - totalRead
|
|
)
|
|
) > 0
|
|
)
|
|
{
|
|
totalRead += bytesRead;
|
|
}
|
|
|
|
Assert.Equal(testData.Length, totalRead);
|
|
Assert.Equal(testData, decompressed);
|
|
}
|
|
}
|
|
}
|