mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-24 16:05:27 +00:00
make Writable interfaces for archive
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.IO;
|
||||
using SharpCompress.Readers;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SharpCompress.Archives;
|
||||
|
||||
public abstract class AbstractWritableArchive<TEntry, TVolume>
|
||||
: AbstractArchive<TEntry, TVolume>,
|
||||
IWritableArchive
|
||||
IWritableArchive, IWritableAsyncArchive
|
||||
where TEntry : IArchiveEntry
|
||||
where TVolume : IVolume
|
||||
{
|
||||
@@ -83,12 +83,12 @@ public abstract class AbstractWritableArchive<TEntry, TVolume>
|
||||
}
|
||||
}
|
||||
|
||||
void IWritableArchive.RemoveEntry(IArchiveEntry entry) => RemoveEntry((TEntry)entry);
|
||||
void IWritableArchiveCommon.RemoveEntry(IArchiveEntry entry) => RemoveEntry((TEntry)entry);
|
||||
|
||||
public TEntry AddEntry(string key, Stream source, long size = 0, DateTime? modified = null) =>
|
||||
AddEntry(key, source, false, size, modified);
|
||||
|
||||
IArchiveEntry IWritableArchive.AddEntry(
|
||||
IArchiveEntry IWritableArchiveCommon.AddEntry(
|
||||
string key,
|
||||
Stream source,
|
||||
bool closeStream,
|
||||
@@ -96,7 +96,7 @@ public abstract class AbstractWritableArchive<TEntry, TVolume>
|
||||
DateTime? modified
|
||||
) => AddEntry(key, source, closeStream, size, modified);
|
||||
|
||||
IArchiveEntry IWritableArchive.AddDirectoryEntry(string key, DateTime? modified) =>
|
||||
IArchiveEntry IWritableArchiveCommon.AddDirectoryEntry(string key, DateTime? modified) =>
|
||||
AddDirectoryEntry(key, modified);
|
||||
|
||||
public TEntry AddEntry(
|
||||
|
||||
@@ -88,7 +88,7 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -108,14 +108,14 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,14 +124,14 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -140,14 +140,14 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,14 +156,14 @@ public class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZipVolume>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static GZipArchive Create() => new();
|
||||
|
||||
@@ -39,4 +39,6 @@ public interface IArchive : IDisposable
|
||||
/// The total size of the files as uncompressed in the archive.
|
||||
/// </summary>
|
||||
long TotalUncompressSize { get; }
|
||||
|
||||
bool IsEncrypted { get; }
|
||||
}
|
||||
|
||||
@@ -6,8 +6,13 @@ using SharpCompress.Writers;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public interface IWritableArchive : IArchive
|
||||
public interface IWritableArchiveCommon
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this to pause entry rebuilding when adding large collections of entries. Dispose when complete. A using statement is recommended.
|
||||
/// </summary>
|
||||
/// <returns>IDisposeable to resume entry rebuilding</returns>
|
||||
IDisposable PauseEntryRebuilding();
|
||||
void RemoveEntry(IArchiveEntry entry);
|
||||
|
||||
IArchiveEntry AddEntry(
|
||||
@@ -19,18 +24,20 @@ public interface IWritableArchive : IArchive
|
||||
);
|
||||
|
||||
IArchiveEntry AddDirectoryEntry(string key, DateTime? modified = null);
|
||||
}
|
||||
|
||||
public interface IWritableArchive : IArchive, IWritableArchiveCommon
|
||||
{
|
||||
|
||||
void SaveTo(Stream stream, WriterOptions options);
|
||||
}
|
||||
|
||||
public interface IWritableAsyncArchive : IAsyncArchive, IWritableArchiveCommon
|
||||
{
|
||||
|
||||
ValueTask SaveToAsync(
|
||||
Stream stream,
|
||||
WriterOptions options,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Use this to pause entry rebuilding when adding large collections of entries. Dispose when complete. A using statement is recommended.
|
||||
/// </summary>
|
||||
/// <returns>IDisposeable to resume entry rebuilding</returns>
|
||||
IDisposable PauseEntryRebuilding();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public static class IWritableArchiveCommonExtensions
|
||||
{
|
||||
public static void AddEntry(
|
||||
this IWritableArchive writableArchive,
|
||||
string entryPath,
|
||||
string filePath
|
||||
)
|
||||
{
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
throw new FileNotFoundException("Could not AddEntry: " + filePath);
|
||||
}
|
||||
writableArchive.AddEntry(
|
||||
entryPath,
|
||||
new FileInfo(filePath).OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
}
|
||||
|
||||
public static void AddAllFromDirectory(
|
||||
this IWritableArchiveCommon writableArchive,
|
||||
string filePath,
|
||||
string searchPattern = "*.*",
|
||||
SearchOption searchOption = SearchOption.AllDirectories
|
||||
)
|
||||
{
|
||||
using (writableArchive.PauseEntryRebuilding())
|
||||
{
|
||||
foreach (var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption))
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
writableArchive.AddEntry(
|
||||
path.Substring(filePath.Length),
|
||||
fileInfo.OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IArchiveEntry AddEntry(
|
||||
this IWritableArchiveCommon writableArchive,
|
||||
string key,
|
||||
string file
|
||||
) => AddEntry(writableArchive, key, new FileInfo(file));
|
||||
|
||||
public static IArchiveEntry AddEntry(
|
||||
this IWritableArchiveCommon writableArchive,
|
||||
string key,
|
||||
FileInfo fileInfo
|
||||
)
|
||||
{
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
throw new ArgumentException("FileInfo does not exist.");
|
||||
}
|
||||
return writableArchive.AddEntry(
|
||||
key,
|
||||
fileInfo.OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,106 +1,25 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Writers;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public static class IWritableArchiveExtensions
|
||||
{
|
||||
public static void AddEntry(
|
||||
this IWritableArchive writableArchive,
|
||||
string entryPath,
|
||||
string filePath
|
||||
)
|
||||
{
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
throw new FileNotFoundException("Could not AddEntry: " + filePath);
|
||||
}
|
||||
writableArchive.AddEntry(
|
||||
entryPath,
|
||||
new FileInfo(filePath).OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
}
|
||||
|
||||
public static void SaveTo(
|
||||
this IWritableArchive writableArchive,
|
||||
string filePath,
|
||||
WriterOptions options
|
||||
) => writableArchive.SaveTo(new FileInfo(filePath), options);
|
||||
WriterOptions? options = null
|
||||
) => writableArchive.SaveTo(new FileInfo(filePath), options ?? new (CompressionType.Deflate));
|
||||
|
||||
public static void SaveTo(
|
||||
this IWritableArchive writableArchive,
|
||||
FileInfo fileInfo,
|
||||
WriterOptions options
|
||||
WriterOptions? options = null
|
||||
)
|
||||
{
|
||||
using var stream = fileInfo.Open(FileMode.Create, FileAccess.Write);
|
||||
writableArchive.SaveTo(stream, options);
|
||||
}
|
||||
|
||||
public static ValueTask SaveToAsync(
|
||||
this IWritableArchive writableArchive,
|
||||
string filePath,
|
||||
WriterOptions options,
|
||||
CancellationToken cancellationToken = default
|
||||
) => writableArchive.SaveToAsync(new FileInfo(filePath), options, cancellationToken);
|
||||
|
||||
public static async ValueTask SaveToAsync(
|
||||
this IWritableArchive writableArchive,
|
||||
FileInfo fileInfo,
|
||||
WriterOptions options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
using var stream = fileInfo.Open(FileMode.Create, FileAccess.Write);
|
||||
await writableArchive.SaveToAsync(stream, options, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static void AddAllFromDirectory(
|
||||
this IWritableArchive writableArchive,
|
||||
string filePath,
|
||||
string searchPattern = "*.*",
|
||||
SearchOption searchOption = SearchOption.AllDirectories
|
||||
)
|
||||
{
|
||||
using (writableArchive.PauseEntryRebuilding())
|
||||
{
|
||||
foreach (var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption))
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
writableArchive.AddEntry(
|
||||
path.Substring(filePath.Length),
|
||||
fileInfo.OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IArchiveEntry AddEntry(
|
||||
this IWritableArchive writableArchive,
|
||||
string key,
|
||||
FileInfo fileInfo
|
||||
)
|
||||
{
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
throw new ArgumentException("FileInfo does not exist.");
|
||||
}
|
||||
return writableArchive.AddEntry(
|
||||
key,
|
||||
fileInfo.OpenRead(),
|
||||
true,
|
||||
fileInfo.Length,
|
||||
fileInfo.LastWriteTime
|
||||
);
|
||||
writableArchive.SaveTo(stream, options?? new (CompressionType.Deflate));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Writers;
|
||||
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public static class IWritableAsyncArchiveExtensions
|
||||
{
|
||||
public static ValueTask SaveToAsync(
|
||||
this IWritableAsyncArchive writableArchive,
|
||||
string filePath,
|
||||
WriterOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) => writableArchive.SaveToAsync(new FileInfo(filePath), options ?? new (CompressionType.Deflate), cancellationToken);
|
||||
|
||||
public static async ValueTask SaveToAsync(
|
||||
this IWritableAsyncArchive writableArchive,
|
||||
FileInfo fileInfo,
|
||||
WriterOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
using var stream = fileInfo.Open(FileMode.Create, FileAccess.Write);
|
||||
await writableArchive.SaveToAsync(stream, options?? new (CompressionType.Deflate), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common.Rar;
|
||||
|
||||
namespace SharpCompress.Archives.Rar;
|
||||
|
||||
@@ -7,12 +9,25 @@ public static class RarArchiveExtensions
|
||||
/// <summary>
|
||||
/// RarArchive is the first volume of a multi-part archive. If MultipartVolume is true and IsFirstVolume is false then the first volume file must be missing.
|
||||
/// </summary>
|
||||
public static bool IsFirstVolume(this RarArchive archive) =>
|
||||
archive.Volumes.First().IsFirstVolume;
|
||||
public static bool IsFirstVolume(this IRarArchive archive) =>
|
||||
archive.Volumes.Cast<RarVolume>().First().IsFirstVolume;
|
||||
|
||||
/// <summary>
|
||||
/// RarArchive is part of a multi-part archive.
|
||||
/// </summary>
|
||||
public static bool IsMultipartVolume(this RarArchive archive) =>
|
||||
archive.Volumes.First().IsMultiVolume;
|
||||
public static bool IsMultipartVolume(this IRarArchive archive) =>
|
||||
archive.Volumes.Cast<RarVolume>().First().IsMultiVolume;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// RarArchive is the first volume of a multi-part archive. If MultipartVolume is true and IsFirstVolume is false then the first volume file must be missing.
|
||||
/// </summary>
|
||||
public static async ValueTask<bool> IsFirstVolumeAsync(this IRarAsyncArchive archive) =>
|
||||
(await archive.VolumesAsync.CastAsync<RarVolume>().FirstAsync()).IsFirstVolume;
|
||||
|
||||
/// <summary>
|
||||
/// RarArchive is part of a multi-part archive.
|
||||
/// </summary>
|
||||
public static async ValueTask<bool> IsMultipartVolumeAsync(this IRarAsyncArchive archive) =>
|
||||
(await archive.VolumesAsync.CastAsync<RarVolume>().FirstAsync()).IsMultiVolume;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,23 @@ using SharpCompress.Readers.Rar;
|
||||
|
||||
namespace SharpCompress.Archives.Rar;
|
||||
|
||||
public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
public interface IRarArchiveCommon
|
||||
{
|
||||
|
||||
|
||||
int MinVersion { get; }
|
||||
int MaxVersion { get; }
|
||||
}
|
||||
|
||||
public interface IRarArchive : IArchive, IRarArchiveCommon
|
||||
{
|
||||
}
|
||||
|
||||
public interface IRarAsyncArchive : IAsyncArchive, IRarArchiveCommon
|
||||
{
|
||||
}
|
||||
|
||||
public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>, IRarArchive
|
||||
{
|
||||
private bool _disposed;
|
||||
internal Lazy<IRarUnpack> UnpackV2017 { get; } =
|
||||
@@ -103,7 +119,7 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="options"></param>
|
||||
public static IArchive Open(string filePath, ReaderOptions? options = null)
|
||||
public static IRarArchive Open(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
@@ -121,7 +137,7 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="options"></param>
|
||||
public static IArchive Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
public static IRarArchive Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new RarArchive(
|
||||
@@ -138,7 +154,7 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
public static IArchive Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IRarArchive Open(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -155,7 +171,7 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(
|
||||
public static IRarArchive Open(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -176,7 +192,7 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// </summary>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
public static IRarArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams.ToArray();
|
||||
@@ -195,14 +211,14 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(stream, readerOptions);
|
||||
return (IRarAsyncArchive)Open(stream, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,14 +227,14 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IRarAsyncArchive)Open(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -227,14 +243,14 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(streams, readerOptions);
|
||||
return (IRarAsyncArchive)Open(streams, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,14 +259,14 @@ public class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IRarAsyncArchive)Open(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsRarFile(string filePath) => IsRarFile(new FileInfo(filePath));
|
||||
|
||||
@@ -22,7 +22,7 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
@@ -33,7 +33,7 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new TarArchive(
|
||||
@@ -50,7 +50,7 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(
|
||||
public static IWritableArchive Open(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -71,7 +71,7 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// </summary>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams.ToArray();
|
||||
@@ -89,7 +89,7 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -109,14 +109,24 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
string file,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(new FileInfo(file), readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,14 +135,14 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -141,14 +151,14 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,14 +167,14 @@ public class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVolume>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsTarFile(string filePath) => IsTarFile(new FileInfo(filePath));
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
@@ -54,7 +54,7 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new ZipArchive(
|
||||
@@ -71,7 +71,7 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(
|
||||
public static IWritableArchive Open(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -92,7 +92,7 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams.ToArray();
|
||||
@@ -110,7 +110,7 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -124,14 +124,14 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
);
|
||||
}
|
||||
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(path, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(path, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -140,14 +140,14 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,14 +156,14 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// <param name="fileInfo"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -172,14 +172,14 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -188,14 +188,14 @@ public class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVolume>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsZipFile(
|
||||
|
||||
@@ -116,6 +116,24 @@ public static class AsyncEnumerableExtensions
|
||||
}
|
||||
}
|
||||
|
||||
public static async ValueTask<T> SingleAsync<T>(
|
||||
this IAsyncEnumerable<T> source,
|
||||
Func<T, bool> predicate
|
||||
)
|
||||
{
|
||||
var enumerator = source.WhereAsync(predicate).GetAsyncEnumerator();
|
||||
if (!await enumerator.MoveNextAsync())
|
||||
{
|
||||
throw new InvalidOperationException("The source sequence is empty.");
|
||||
}
|
||||
var value = enumerator.Current;
|
||||
if (await enumerator.MoveNextAsync())
|
||||
{
|
||||
throw new InvalidOperationException("The source sequence contains more than one element.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static async ValueTask<T> FirstAsync<T>(this IAsyncEnumerable<T> source)
|
||||
{
|
||||
await foreach (var item in source)
|
||||
|
||||
@@ -216,9 +216,9 @@
|
||||
"net10.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.1, )",
|
||||
"resolved": "10.0.1",
|
||||
"contentHash": "ISahzLHsHY7vrwqr2p1YWZ+gsxoBRtH7gWRDK8fDUst9pp2He0GiesaqEfeX0V8QMCJM3eNEHGGpnIcPjFo2NQ=="
|
||||
"requested": "[10.0.0, )",
|
||||
"resolved": "10.0.0",
|
||||
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -601,7 +601,7 @@ public class ArchiveTests : ReaderTests
|
||||
)
|
||||
)
|
||||
await using (
|
||||
var archive = await archiveFactory.OpenAsync(
|
||||
var archive = archiveFactory.OpenAsync(
|
||||
new AsyncOnlyStream(stream),
|
||||
readerOptions
|
||||
)
|
||||
|
||||
@@ -48,8 +48,7 @@ public class GZipArchiveAsyncTests : ArchiveTests
|
||||
await using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz")))
|
||||
#endif
|
||||
{
|
||||
IAsyncArchive archive = await GZipArchive.OpenAsync(stream);
|
||||
try
|
||||
await using (var archive = GZipArchive.OpenAsync(stream))
|
||||
{
|
||||
var entry = await archive.EntriesAsync.FirstAsync();
|
||||
await entry.WriteToFileAsync(Path.Combine(SCRATCH_FILES_PATH, entry.Key.NotNull()));
|
||||
@@ -61,10 +60,6 @@ public class GZipArchiveAsyncTests : ArchiveTests
|
||||
Assert.Equal(size, scratch.Length);
|
||||
Assert.Equal(size, test.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
archive.DisposeAsync().AsTask().Wait();
|
||||
}
|
||||
}
|
||||
CompareArchivesByPath(
|
||||
Path.Combine(SCRATCH_FILES_PATH, "Tar.tar"),
|
||||
@@ -81,18 +76,12 @@ public class GZipArchiveAsyncTests : ArchiveTests
|
||||
#else
|
||||
await using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
|
||||
#endif
|
||||
IAsyncArchive archive = await GZipArchive.OpenAsync(stream);
|
||||
try
|
||||
await using (var archive = GZipArchive.OpenAsync(stream))
|
||||
{
|
||||
await Assert.ThrowsAsync<InvalidFormatException>(() =>
|
||||
archive.AddEntry("jpg\\test.jpg", jpg)
|
||||
);
|
||||
Assert.Throws<InvalidFormatException>(() =>
|
||||
archive.AddEntry("jpg\\test.jpg", jpg));
|
||||
await archive.SaveToAsync(Path.Combine(SCRATCH_FILES_PATH, "Tar.tar.gz"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
await archive.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -36,59 +36,61 @@ public class RarReaderAsyncTests : ReaderTests
|
||||
"Rar5.multi.part06.rar",
|
||||
]);
|
||||
|
||||
private async ValueTask DoRar_Multi_Reader_Async(string[] archives)
|
||||
{
|
||||
using (
|
||||
var reader = RarReader.Open(
|
||||
archives
|
||||
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
|
||||
.Select(p => File.OpenRead(p))
|
||||
)
|
||||
)
|
||||
{
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
}
|
||||
private async ValueTask DoRar_Multi_Reader_Async(string[] archives)
|
||||
{
|
||||
using (
|
||||
IReader baseReader = RarReader.Open(
|
||||
archives
|
||||
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
|
||||
.Select(p => File.OpenRead(p))
|
||||
)
|
||||
)
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async ValueTask Rar_Multi_Reader_Encrypted_Async() =>
|
||||
await Assert.ThrowsAsync<InvalidFormatException>(async () =>
|
||||
{
|
||||
string[] archives =
|
||||
[
|
||||
"Rar.EncryptedParts.part01.rar",
|
||||
"Rar.EncryptedParts.part02.rar",
|
||||
"Rar.EncryptedParts.part03.rar",
|
||||
"Rar.EncryptedParts.part04.rar",
|
||||
"Rar.EncryptedParts.part05.rar",
|
||||
"Rar.EncryptedParts.part06.rar",
|
||||
];
|
||||
using (
|
||||
var reader = RarReader.Open(
|
||||
archives
|
||||
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
|
||||
.Select(p => File.OpenRead(p)),
|
||||
new ReaderOptions { Password = "test" }
|
||||
)
|
||||
)
|
||||
{
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
});
|
||||
[Fact]
|
||||
public async ValueTask Rar_Multi_Reader_Encrypted_Async() =>
|
||||
await Assert.ThrowsAsync<InvalidFormatException>(async () =>
|
||||
{
|
||||
string[] archives =
|
||||
[
|
||||
"Rar.EncryptedParts.part01.rar",
|
||||
"Rar.EncryptedParts.part02.rar",
|
||||
"Rar.EncryptedParts.part03.rar",
|
||||
"Rar.EncryptedParts.part04.rar",
|
||||
"Rar.EncryptedParts.part05.rar",
|
||||
"Rar.EncryptedParts.part06.rar",
|
||||
];
|
||||
using (
|
||||
IReader baseReader = RarReader.Open(
|
||||
archives
|
||||
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
|
||||
.Select(p => File.OpenRead(p)),
|
||||
new ReaderOptions { Password = "test" }
|
||||
)
|
||||
)
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public async ValueTask Rar_Multi_Reader_Delete_Files_Async() =>
|
||||
@@ -121,30 +123,31 @@ public class RarReaderAsyncTests : ReaderTests
|
||||
Path.Combine(SCRATCH2_FILES_PATH, file)
|
||||
);
|
||||
}
|
||||
var streams = archives
|
||||
.Select(s => Path.Combine(SCRATCH2_FILES_PATH, s))
|
||||
.Select(File.OpenRead)
|
||||
.ToList();
|
||||
using (var reader = RarReader.Open(streams))
|
||||
{
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (var stream in streams)
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
VerifyFiles();
|
||||
var streams = archives
|
||||
.Select(s => Path.Combine(SCRATCH2_FILES_PATH, s))
|
||||
.Select(File.OpenRead)
|
||||
.ToList();
|
||||
using (IReader baseReader = RarReader.Open(streams))
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (var stream in streams)
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
VerifyFiles();
|
||||
|
||||
foreach (var file in archives.Select(s => Path.Combine(SCRATCH2_FILES_PATH, s)))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
foreach (var file in archives.Select(s => Path.Combine(SCRATCH2_FILES_PATH, s)))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -271,23 +274,24 @@ public class RarReaderAsyncTests : ReaderTests
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async ValueTask Rar_Jpg_Reader_Async()
|
||||
{
|
||||
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg")))
|
||||
using (var reader = RarReader.Open(stream, new ReaderOptions { LookForHeader = true }))
|
||||
{
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
}
|
||||
[Fact]
|
||||
public async ValueTask Rar_Jpg_Reader_Async()
|
||||
{
|
||||
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg")))
|
||||
using (IReader baseReader = RarReader.Open(stream, new ReaderOptions { LookForHeader = true }))
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
|
||||
await reader.WriteEntryToDirectoryAsync(
|
||||
SCRATCH_FILES_PATH,
|
||||
new ExtractionOptions { ExtractFullPath = true, Overwrite = true }
|
||||
);
|
||||
}
|
||||
}
|
||||
VerifyFiles();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async ValueTask Rar_Solid_Reader_Async() =>
|
||||
|
||||
@@ -47,7 +47,7 @@ public class TarArchiveAsyncTests : ArchiveTests
|
||||
var unmodified = Path.Combine(SCRATCH2_FILES_PATH, archive);
|
||||
using (var archive2 = TarArchive.Open(unmodified))
|
||||
{
|
||||
Assert.Equal(1, archive2.Entries.Count);
|
||||
Assert.Equal(1, archive2.Entries.Count());
|
||||
Assert.Contains(filename, archive2.Entries.Select(entry => entry.Key));
|
||||
|
||||
foreach (var entry in archive2.Entries)
|
||||
@@ -91,7 +91,7 @@ public class TarArchiveAsyncTests : ArchiveTests
|
||||
var unmodified = Path.Combine(SCRATCH2_FILES_PATH, archive);
|
||||
using (var archive2 = TarArchive.Open(unmodified))
|
||||
{
|
||||
Assert.Equal(1, archive2.Entries.Count);
|
||||
Assert.Equal(1, archive2.Entries.Count());
|
||||
Assert.Contains(longFilename, archive2.Entries.Select(entry => entry.Key));
|
||||
|
||||
foreach (var entry in archive2.Entries)
|
||||
@@ -128,7 +128,7 @@ public class TarArchiveAsyncTests : ArchiveTests
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.mod.tar");
|
||||
var modified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar");
|
||||
|
||||
using (var archive = TarArchive.Open(unmodified))
|
||||
await using (var archive = TarArchive.OpenAsync(unmodified))
|
||||
{
|
||||
archive.AddEntry("jpg\\test.jpg", jpg);
|
||||
await archive.SaveToAsync(scratchPath, new WriterOptions(CompressionType.None));
|
||||
@@ -143,9 +143,9 @@ public class TarArchiveAsyncTests : ArchiveTests
|
||||
var modified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.mod.tar");
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Tar.noEmptyDirs.tar");
|
||||
|
||||
using (var archive = TarArchive.Open(unmodified))
|
||||
await using (var archive = TarArchive.OpenAsync(unmodified))
|
||||
{
|
||||
var entry = archive.Entries.Single(x =>
|
||||
var entry = await archive.EntriesAsync.SingleAsync(x =>
|
||||
x.Key.NotNull().EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
archive.RemoveEntry(entry);
|
||||
|
||||
@@ -49,7 +49,7 @@ public class TarArchiveTests : ArchiveTests
|
||||
var unmodified = Path.Combine(SCRATCH2_FILES_PATH, archive);
|
||||
using (var archive2 = TarArchive.Open(unmodified))
|
||||
{
|
||||
Assert.Equal(1, archive2.Entries.Count);
|
||||
Assert.Equal(1, archive2.Entries.Count());
|
||||
Assert.Contains(filename, archive2.Entries.Select(entry => entry.Key));
|
||||
|
||||
foreach (var entry in archive2.Entries)
|
||||
@@ -67,7 +67,7 @@ public class TarArchiveTests : ArchiveTests
|
||||
{
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "very long filename.tar");
|
||||
using var archive = TarArchive.Open(unmodified);
|
||||
Assert.Equal(5, archive.Entries.Count);
|
||||
Assert.Equal(5, archive.Entries.Count());
|
||||
Assert.Contains("very long filename/", archive.Entries.Select(entry => entry.Key));
|
||||
Assert.Contains(
|
||||
"very long filename/very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename very long filename.jpg",
|
||||
@@ -109,7 +109,7 @@ public class TarArchiveTests : ArchiveTests
|
||||
var unmodified = Path.Combine(SCRATCH2_FILES_PATH, archive);
|
||||
using (var archive2 = TarArchive.Open(unmodified))
|
||||
{
|
||||
Assert.Equal(1, archive2.Entries.Count);
|
||||
Assert.Equal(1, archive2.Entries.Count());
|
||||
Assert.Contains(longFilename, archive2.Entries.Select(entry => entry.Key));
|
||||
|
||||
foreach (var entry in archive2.Entries)
|
||||
@@ -127,7 +127,7 @@ public class TarArchiveTests : ArchiveTests
|
||||
{
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "ustar with long names.tar");
|
||||
using var archive = TarArchive.Open(unmodified);
|
||||
Assert.Equal(6, archive.Entries.Count);
|
||||
Assert.Equal(6, archive.Entries.Count());
|
||||
Assert.Contains("Directory/", archive.Entries.Select(entry => entry.Key));
|
||||
Assert.Contains(
|
||||
"Directory/Some file with veeeeeeeeeery loooooooooong name",
|
||||
|
||||
@@ -126,10 +126,9 @@ public class ZipArchiveAsyncTests : ArchiveTests
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.noEmptyDirs.zip");
|
||||
var modified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod.zip");
|
||||
|
||||
using (IArchive baseArchive = ZipArchive.Open(unmodified))
|
||||
await using (var archive = ZipArchive.OpenAsync(unmodified))
|
||||
{
|
||||
IWritableArchive archive = (IWritableArchive)baseArchive;
|
||||
var entry = archive.Entries.Single(x =>
|
||||
var entry = await archive.EntriesAsync.SingleAsync(x =>
|
||||
x.Key.NotNull().EndsWith("jpg", StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
archive.RemoveEntry(entry);
|
||||
@@ -150,9 +149,8 @@ public class ZipArchiveAsyncTests : ArchiveTests
|
||||
var unmodified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.mod.zip");
|
||||
var modified = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.noEmptyDirs.zip");
|
||||
|
||||
using (IArchive baseArchive = ZipArchive.Open(unmodified))
|
||||
await using (var archive = ZipArchive.OpenAsync(unmodified))
|
||||
{
|
||||
IWritableArchive archive = (IWritableArchive)baseArchive;
|
||||
archive.AddEntry("jpg\\test.jpg", jpg);
|
||||
|
||||
WriterOptions writerOptions = new ZipWriterOptions(CompressionType.Deflate);
|
||||
|
||||
@@ -495,7 +495,7 @@ public class ZipArchiveTests : ArchiveTests
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
var isComplete = reader.IsComplete;
|
||||
Assert.Equal(1, reader.Volumes.Count);
|
||||
Assert.Equal(1, reader.Volumes.Count());
|
||||
|
||||
var expectedComment =
|
||||
"Encoding:utf-8 || Compression:Deflate levelDefault || Encrypt:None || ZIP64:Always\r\nCreated at 2017-Jan-23 14:10:43 || DotNetZip Tool v1.9.1.8\r\nTest zip64 archive";
|
||||
@@ -708,7 +708,7 @@ public class ZipArchiveTests : ArchiveTests
|
||||
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.LongComment.zip");
|
||||
|
||||
using var za = ZipArchive.Open(zipPath);
|
||||
var count = za.Entries.Count;
|
||||
var count = za.Entries.Count();
|
||||
Assert.Equal(1, count);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,8 +121,9 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
using (
|
||||
Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip"))
|
||||
)
|
||||
using (var reader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
using (IReader baseReader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
@@ -191,8 +192,11 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.WinzipAES.zip"))
|
||||
)
|
||||
)
|
||||
using (var reader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
using (
|
||||
IReader baseReader = ZipReader.Open(stream, new ReaderOptions { Password = "test" })
|
||||
)
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
@@ -216,8 +220,9 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip"))
|
||||
)
|
||||
)
|
||||
using (var reader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
using (IReader baseReader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
@@ -242,8 +247,9 @@ public class ZipReaderAsyncTests : ReaderTests
|
||||
File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "zipcrypto.zip"))
|
||||
)
|
||||
)
|
||||
using (var reader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
using (IReader baseReader = ZipReader.Open(stream, new ReaderOptions { Password = "test" }))
|
||||
{
|
||||
IAsyncReader reader = (IAsyncReader)baseReader;
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
|
||||
Reference in New Issue
Block a user