This commit is contained in:
Adam Hathcock
2026-01-13 13:58:31 +00:00
parent ec7d2e357d
commit cdca909d84
4 changed files with 65 additions and 42 deletions

View File

@@ -8,7 +8,9 @@ using SharpCompress.IO;
namespace SharpCompress.Writers;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public abstract class AbstractWriter(ArchiveType type, WriterOptions writerOptions) : IWriter, IAsyncWriter
public abstract class AbstractWriter(ArchiveType type, WriterOptions writerOptions)
: IWriter,
IAsyncWriter
{
private bool _isDisposed;

View File

@@ -10,8 +10,7 @@ public static class IWriterExtensions
{
extension(IWriter writer)
{
public void Write(string entryPath, Stream source) =>
writer.Write(entryPath, source, null);
public void Write(string entryPath, Stream source) => writer.Write(entryPath, source, null);
public void Write(string entryPath, FileInfo source)
{
@@ -27,15 +26,17 @@ public static class IWriterExtensions
public void Write(string entryPath, string source) =>
writer.Write(entryPath, new FileInfo(source));
public void WriteAll(string directory,
string searchPattern = "*",
SearchOption option = SearchOption.TopDirectoryOnly
public void WriteAll(
string directory,
string searchPattern = "*",
SearchOption option = SearchOption.TopDirectoryOnly
) => writer.WriteAll(directory, searchPattern, null, option);
public void WriteAll(string directory,
string searchPattern = "*",
Func<string, bool>? fileSearchFunc = null,
SearchOption option = SearchOption.TopDirectoryOnly
public void WriteAll(
string directory,
string searchPattern = "*",
Func<string, bool>? fileSearchFunc = null,
SearchOption option = SearchOption.TopDirectoryOnly
)
{
if (!Directory.Exists(directory))
@@ -46,8 +47,8 @@ public static class IWriterExtensions
fileSearchFunc ??= n => true;
foreach (
var file in Directory
.EnumerateFiles(directory, searchPattern, option)
.Where(fileSearchFunc)
.EnumerateFiles(directory, searchPattern, option)
.Where(fileSearchFunc)
)
{
writer.Write(file.Substring(directory.Length), file);
@@ -60,14 +61,16 @@ public static class IWriterExtensions
extension(IAsyncWriter writer)
{
public ValueTask WriteAsync(string entryPath,
Stream source,
CancellationToken cancellationToken = default
public ValueTask WriteAsync(
string entryPath,
Stream source,
CancellationToken cancellationToken = default
) => writer.WriteAsync(entryPath, source, null, cancellationToken);
public async ValueTask WriteAsync(string entryPath,
FileInfo source,
CancellationToken cancellationToken = default
public async ValueTask WriteAsync(
string entryPath,
FileInfo source,
CancellationToken cancellationToken = default
)
{
if (!source.Exists)
@@ -76,26 +79,29 @@ public static class IWriterExtensions
}
using var stream = source.OpenRead();
await writer
.WriteAsync(entryPath, stream, source.LastWriteTime, cancellationToken)
.ConfigureAwait(false);
.WriteAsync(entryPath, stream, source.LastWriteTime, cancellationToken)
.ConfigureAwait(false);
}
public ValueTask WriteAsync(string entryPath,
string source,
CancellationToken cancellationToken = default
public ValueTask WriteAsync(
string entryPath,
string source,
CancellationToken cancellationToken = default
) => writer.WriteAsync(entryPath, new FileInfo(source), cancellationToken);
public ValueTask WriteAllAsync(string directory,
string searchPattern = "*",
SearchOption option = SearchOption.TopDirectoryOnly,
CancellationToken cancellationToken = default
public ValueTask WriteAllAsync(
string directory,
string searchPattern = "*",
SearchOption option = SearchOption.TopDirectoryOnly,
CancellationToken cancellationToken = default
) => writer.WriteAllAsync(directory, searchPattern, null, option, cancellationToken);
public async ValueTask WriteAllAsync(string directory,
string searchPattern = "*",
Func<string, bool>? fileSearchFunc = null,
SearchOption option = SearchOption.TopDirectoryOnly,
CancellationToken cancellationToken = default
public async ValueTask WriteAllAsync(
string directory,
string searchPattern = "*",
Func<string, bool>? fileSearchFunc = null,
SearchOption option = SearchOption.TopDirectoryOnly,
CancellationToken cancellationToken = default
)
{
if (!Directory.Exists(directory))
@@ -106,18 +112,19 @@ public static class IWriterExtensions
fileSearchFunc ??= n => true;
foreach (
var file in Directory
.EnumerateFiles(directory, searchPattern, option)
.Where(fileSearchFunc)
.EnumerateFiles(directory, searchPattern, option)
.Where(fileSearchFunc)
)
{
await writer
.WriteAsync(file.Substring(directory.Length), file, cancellationToken)
.ConfigureAwait(false);
.WriteAsync(file.Substring(directory.Length), file, cancellationToken)
.ConfigureAwait(false);
}
}
public ValueTask WriteDirectoryAsync(string directoryName,
CancellationToken cancellationToken = default
public ValueTask WriteDirectoryAsync(
string directoryName,
CancellationToken cancellationToken = default
) => writer.WriteDirectoryAsync(directoryName, null, cancellationToken);
}

View File

@@ -23,7 +23,13 @@ public class GZipWriterAsyncTests : WriterTests
FileAccess.Write
)
)
using (var writer = WriterFactory.OpenAsync(new AsyncOnlyStream(stream), ArchiveType.GZip, CompressionType.GZip))
using (
var writer = WriterFactory.OpenAsync(
new AsyncOnlyStream(stream),
ArchiveType.GZip,
CompressionType.GZip
)
)
{
await writer.WriteAsync("Tar.tar", Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar"));
}
@@ -58,7 +64,11 @@ public class GZipWriterAsyncTests : WriterTests
Assert.Throws<InvalidFormatException>(() =>
{
using Stream stream = File.OpenWrite(Path.Combine(SCRATCH_FILES_PATH, "Tar.tar.gz"));
using var writer = WriterFactory.Open(new AsyncOnlyStream(stream), ArchiveType.GZip, CompressionType.BZip2);
using var writer = WriterFactory.Open(
new AsyncOnlyStream(stream),
ArchiveType.GZip,
CompressionType.BZip2
);
});
[Fact]

View File

@@ -60,7 +60,9 @@ public class ZipTypesLevelsWithCrcRatioAsyncTests : ArchiveTests
// Create zip archive in memory
using var zipStream = new MemoryStream();
using (var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel))
using (
var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel)
)
{
await writer.WriteAsync($"file1_{sizeMb}MiB.txt", new MemoryStream(file1Data));
await writer.WriteAsync($"data/file2_{sizeMb * 2}MiB.txt", new MemoryStream(file2Data));
@@ -191,7 +193,9 @@ public class ZipTypesLevelsWithCrcRatioAsyncTests : ArchiveTests
// Create archive with specified compression and level
using var zipStream = new MemoryStream();
using (var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel))
using (
var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel)
)
{
await writer.WriteAsync(
$"{compressionType}_{compressionLevel}_{sizeMb}MiB.txt",