From 3dff2c67798a7318dfb206300a02ad75f901aa3d Mon Sep 17 00:00:00 2001 From: rameel Date: Tue, 2 Sep 2025 04:07:07 +0500 Subject: [PATCH 1/2] Remove obsolete ZipFileSystem class --- Ramstack.FileSystem.sln | 14 -- src/Ramstack.FileSystem.Zip/README.md | 68 ------- .../Ramstack.FileSystem.Zip.csproj | 66 ------ src/Ramstack.FileSystem.Zip/ZipDirectory.cs | 72 ------- src/Ramstack.FileSystem.Zip/ZipFile.cs | 52 ----- src/Ramstack.FileSystem.Zip/ZipFileSystem.cs | 174 ---------------- .../Ramstack.FileSystem.Zip.Tests.csproj | 28 --- .../ZipFileSystemTests.cs | 190 ------------------ 8 files changed, 664 deletions(-) delete mode 100644 src/Ramstack.FileSystem.Zip/README.md delete mode 100644 src/Ramstack.FileSystem.Zip/Ramstack.FileSystem.Zip.csproj delete mode 100644 src/Ramstack.FileSystem.Zip/ZipDirectory.cs delete mode 100644 src/Ramstack.FileSystem.Zip/ZipFile.cs delete mode 100644 src/Ramstack.FileSystem.Zip/ZipFileSystem.cs delete mode 100644 tests/Ramstack.FileSystem.Zip.Tests/Ramstack.FileSystem.Zip.Tests.csproj delete mode 100644 tests/Ramstack.FileSystem.Zip.Tests/ZipFileSystemTests.cs diff --git a/Ramstack.FileSystem.sln b/Ramstack.FileSystem.sln index 5d5bf89..55ab8f0 100644 --- a/Ramstack.FileSystem.sln +++ b/Ramstack.FileSystem.sln @@ -28,8 +28,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ramstack.FileSystem.Sub", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ramstack.FileSystem.Readonly", "src\Ramstack.FileSystem.Readonly\Ramstack.FileSystem.Readonly.csproj", "{29351AE9-EC9B-4D4F-B9C0-A9DC46409084}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ramstack.FileSystem.Zip", "src\Ramstack.FileSystem.Zip\Ramstack.FileSystem.Zip.csproj", "{A83298E7-63ED-4D40-A7E9-97E635964046}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ramstack.FileSystem.Globbing", "src\Ramstack.FileSystem.Globbing\Ramstack.FileSystem.Globbing.csproj", "{2CA617DF-C8EE-4557-8F3A-3A6A847EA76E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ramstack.FileSystem.Abstractions.Tests", "tests\Ramstack.FileSystem.Abstractions.Tests\Ramstack.FileSystem.Abstractions.Tests.csproj", "{A01A33F1-5A34-4360-8A30-EC84ADC32362}" @@ -42,8 +40,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ramstack.FileSystem.Prefixe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ramstack.FileSystem.Sub.Tests", "tests\Ramstack.FileSystem.Sub.Tests\Ramstack.FileSystem.Sub.Tests.csproj", "{0A8A9C37-708F-4904-AEEA-7B3F203D0B89}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ramstack.FileSystem.Zip.Tests", "tests\Ramstack.FileSystem.Zip.Tests\Ramstack.FileSystem.Zip.Tests.csproj", "{FC3389DF-AF1B-4234-9399-EE9DA7A07E31}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ramstack.FileSystem.Azure.Tests", "tests\Ramstack.FileSystem.Azure.Tests\Ramstack.FileSystem.Azure.Tests.csproj", "{3D5D46F7-AEB5-4CEE-8C9E-8EB4CAF15CCD}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ramstack.FileSystem.Adapters", "src\Ramstack.FileSystem.Adapters\Ramstack.FileSystem.Adapters.csproj", "{CDAD5CF2-ACE0-4114-9DF7-B71474196B9E}" @@ -96,10 +92,6 @@ Global {29351AE9-EC9B-4D4F-B9C0-A9DC46409084}.Debug|Any CPU.Build.0 = Debug|Any CPU {29351AE9-EC9B-4D4F-B9C0-A9DC46409084}.Release|Any CPU.ActiveCfg = Release|Any CPU {29351AE9-EC9B-4D4F-B9C0-A9DC46409084}.Release|Any CPU.Build.0 = Release|Any CPU - {A83298E7-63ED-4D40-A7E9-97E635964046}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A83298E7-63ED-4D40-A7E9-97E635964046}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A83298E7-63ED-4D40-A7E9-97E635964046}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A83298E7-63ED-4D40-A7E9-97E635964046}.Release|Any CPU.Build.0 = Release|Any CPU {2CA617DF-C8EE-4557-8F3A-3A6A847EA76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CA617DF-C8EE-4557-8F3A-3A6A847EA76E}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CA617DF-C8EE-4557-8F3A-3A6A847EA76E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -124,10 +116,6 @@ Global {0A8A9C37-708F-4904-AEEA-7B3F203D0B89}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A8A9C37-708F-4904-AEEA-7B3F203D0B89}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A8A9C37-708F-4904-AEEA-7B3F203D0B89}.Release|Any CPU.Build.0 = Release|Any CPU - {FC3389DF-AF1B-4234-9399-EE9DA7A07E31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC3389DF-AF1B-4234-9399-EE9DA7A07E31}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC3389DF-AF1B-4234-9399-EE9DA7A07E31}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC3389DF-AF1B-4234-9399-EE9DA7A07E31}.Release|Any CPU.Build.0 = Release|Any CPU {3D5D46F7-AEB5-4CEE-8C9E-8EB4CAF15CCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3D5D46F7-AEB5-4CEE-8C9E-8EB4CAF15CCD}.Debug|Any CPU.Build.0 = Debug|Any CPU {3D5D46F7-AEB5-4CEE-8C9E-8EB4CAF15CCD}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -183,14 +171,12 @@ Global {BBAFC684-6EEC-40CC-9016-B1389EB9DC2F} = {778473B7-67CD-4F46-93B8-B2FF5046E492} {5A0795D2-D1C1-4836-8939-89A9655C5993} = {778473B7-67CD-4F46-93B8-B2FF5046E492} {29351AE9-EC9B-4D4F-B9C0-A9DC46409084} = {778473B7-67CD-4F46-93B8-B2FF5046E492} - {A83298E7-63ED-4D40-A7E9-97E635964046} = {778473B7-67CD-4F46-93B8-B2FF5046E492} {2CA617DF-C8EE-4557-8F3A-3A6A847EA76E} = {778473B7-67CD-4F46-93B8-B2FF5046E492} {A01A33F1-5A34-4360-8A30-EC84ADC32362} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {3BC4E91D-ECDC-4BD4-93A7-34C1D7CF2973} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {2AB7DD23-4788-4C94-A63E-BD4AFDDDEFB3} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {757C9DA0-D56A-404B-A54F-026B6F482A01} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {0A8A9C37-708F-4904-AEEA-7B3F203D0B89} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} - {FC3389DF-AF1B-4234-9399-EE9DA7A07E31} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {3D5D46F7-AEB5-4CEE-8C9E-8EB4CAF15CCD} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} {CDAD5CF2-ACE0-4114-9DF7-B71474196B9E} = {778473B7-67CD-4F46-93B8-B2FF5046E492} {92BE6661-6630-442F-A352-8273B38F08C8} = {FDD0140D-CFCB-4875-990F-BF1227CD3CF6} diff --git a/src/Ramstack.FileSystem.Zip/README.md b/src/Ramstack.FileSystem.Zip/README.md deleted file mode 100644 index 85ef7e7..0000000 --- a/src/Ramstack.FileSystem.Zip/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# Ramstack.FileSystem.Zip -[![NuGet](https://img.shields.io/nuget/v/Ramstack.FileSystem.Zip.svg)](https://nuget.org/packages/Ramstack.FileSystem.Zip) -[![MIT](https://img.shields.io/github/license/rameel/ramstack.filesystem)](https://github.com/rameel/ramstack.filesystem/blob/main/LICENSE) - -Provides an implementation of `Ramstack.FileSystem` based on ZIP archives. - -> [!CAUTION] -> The `ZipFileSystem` is **not thread-safe** and allows reading only one file at a time, as it relies on `ZipArchive`, -> which does not support parallel read operations or simultaneous opening of multiple streams. - -> [!WARNING] -> Due to this limitation, the `ZipFileSystem` class is marked as `[Obsolete]`. - -> [!IMPORTANT] -> You may use `ZipFileSystem` only if you can guarantee that: -> - Only one file is open for reading at a time. -> - No file is accessed concurrently. - -## Getting Started - -To install the `Ramstack.FileSystem.Zip` [NuGet package](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) -in your project, run the following command: -```console -dotnet add package Ramstack.FileSystem.Zip -``` -## Usage - -```csharp -using Ramstack.FileSystem.Zip; - -using ZipFileSystem fs = new ZipFileSystem(@"C:\MyArchive.zip"); - -await foreach (VirtualFile file in fs.GetFilesAsync("/")) -{ - Console.WriteLine(node.Name); -} -``` - -## Remark -`ZipFileSystem` is a read-only implementation and does not support for modifying operations. - -## Related Projects -- [Ramstack.FileSystem.Abstractions](https://www.nuget.org/packages/Ramstack.FileSystem.Abstractions) - Provides a virtual file system abstraction. -- [Ramstack.FileSystem.Physical](https://www.nuget.org/packages/Ramstack.FileSystem.Physical) - Provides an implementation based on the local file system. -- [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. -- [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. -- [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. -- [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. -- [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. -- [Ramstack.FileSystem.Sub](https://www.nuget.org/packages/Ramstack.FileSystem.Sub) - Wraps the underlying file system, restricting access to a specific subpath. -- [Ramstack.FileSystem.Adapters](https://www.nuget.org/packages/Ramstack.FileSystem.Adapters) - Provides integration with `Microsoft.Extensions.FileProviders`. -- [Ramstack.FileSystem.Composite](https://www.nuget.org/packages/Ramstack.FileSystem.Composite) - Provides an implementation that combines multiple file systems into a single composite file system. - -## Supported versions - -| | Version | -|------|----------------| -| .NET | 6, 7, 8, 9, 10 | - -## Contributions - -Bug reports and contributions are welcome. - -## License - -This package is released as open source under the **MIT License**. -See the [LICENSE](https://github.com/rameel/ramstack.virtualfiles/blob/main/LICENSE) file for more details. diff --git a/src/Ramstack.FileSystem.Zip/Ramstack.FileSystem.Zip.csproj b/src/Ramstack.FileSystem.Zip/Ramstack.FileSystem.Zip.csproj deleted file mode 100644 index 043715f..0000000 --- a/src/Ramstack.FileSystem.Zip/Ramstack.FileSystem.Zip.csproj +++ /dev/null @@ -1,66 +0,0 @@ - - - - net6.0 - Provides an implementation of Ramstack.FileSystem for managing files within ZIP archives. - enable - enable - preview - true - true - - - - 649;1591 - CS8600;CS8601;CS8602;CS8603;CS8604;CS8610;CS8613;CS8614;CS8618;CS8619;CS8620;CS8625;CS8643;CS8653;CS8714 - - - - https://github.com/rameel/ramstack.filesystem - Rameel - filesystem;fileprovider;zip - https://github.com/rameel/ramstack.filesystem#readme - README.md - MIT - true - snupkg - true - true - true - true - - - - true - - - - - Properties\AssemblyInfo.cs - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - Properties\README.md - True - \ - - - - diff --git a/src/Ramstack.FileSystem.Zip/ZipDirectory.cs b/src/Ramstack.FileSystem.Zip/ZipDirectory.cs deleted file mode 100644 index 4fd2d01..0000000 --- a/src/Ramstack.FileSystem.Zip/ZipDirectory.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Diagnostics; - -using Ramstack.FileSystem.Utilities; - -namespace Ramstack.FileSystem.Zip; - -/// -/// Represents directory contents and file information within a ZIP archive for the specified path. -/// -[Obsolete] -[DebuggerTypeProxy(typeof(ZipDirectoryDebuggerProxy))] -internal sealed class ZipDirectory : VirtualDirectory -{ - private readonly ZipFileSystem _fileSystem; - private readonly List _nodes = []; - - /// - public override IVirtualFileSystem FileSystem => _fileSystem; - - /// - /// Initializes a new instance of the class. - /// - /// The file system associated with this directory. - /// The path of the directory. - public ZipDirectory(ZipFileSystem fileSystem, string path) : base(path) => - _fileSystem = fileSystem; - - /// - protected override ValueTask GetPropertiesCoreAsync(CancellationToken cancellationToken) => - new ValueTask(VirtualNodeProperties.None); - - /// - protected override ValueTask ExistsCoreAsync(CancellationToken cancellationToken) => - new ValueTask(true); - - /// - protected override ValueTask CreateCoreAsync(CancellationToken cancellationToken) => - default; - - /// - protected override ValueTask DeleteCoreAsync(CancellationToken cancellationToken) => - default; - - /// - protected override IAsyncEnumerable GetFileNodesCoreAsync(CancellationToken cancellationToken) => - _nodes.ToAsyncEnumerable(); - - /// - /// Register a file node associated with this directory. - /// - /// The file node associated with this directory. - internal void RegisterNode(VirtualNode node) => - _nodes.Add(node); - - #region Inner type: ZipDirectoryDebuggerProxy - - /// - /// Represents a debugger proxy for viewing the contents of a instance. - /// - /// The instance to provide debugging information for. - private sealed class ZipDirectoryDebuggerProxy(ZipDirectory directory) - { - /// - /// Gets an array of instances representing - /// the files within the associated . - /// - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - public VirtualNode[] Nodes { get; } = directory._nodes.ToArray(); - } - - #endregion -} diff --git a/src/Ramstack.FileSystem.Zip/ZipFile.cs b/src/Ramstack.FileSystem.Zip/ZipFile.cs deleted file mode 100644 index 76b2fe7..0000000 --- a/src/Ramstack.FileSystem.Zip/ZipFile.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.IO.Compression; - -namespace Ramstack.FileSystem.Zip; - -/// -/// Represents a file within a ZIP archive. -/// -[Obsolete] -internal sealed class ZipFile : VirtualFile -{ - private readonly ZipFileSystem _fileSystem; - private readonly ZipArchiveEntry _entry; - - /// - public override IVirtualFileSystem FileSystem => _fileSystem; - - /// - /// Initializes a new instance of the class. - /// - /// The file system associated with this file. - /// The path of the file. - /// The ZIP archive entry representing the file. - public ZipFile(ZipFileSystem fileSystem, string path, ZipArchiveEntry entry) : base(path) => - (_fileSystem, _entry) = (fileSystem, entry); - - /// - protected override ValueTask GetPropertiesCoreAsync(CancellationToken cancellationToken) - { - var properties = VirtualNodeProperties.CreateFileProperties(default, default, lastWriteTime: _entry.LastWriteTime, _entry.Length); - return new ValueTask(properties); - } - - /// - protected override ValueTask ExistsCoreAsync(CancellationToken cancellationToken) => - new ValueTask(true); - - /// - protected override ValueTask OpenReadCoreAsync(CancellationToken cancellationToken) => - new ValueTask(_entry.Open()); - - /// - protected override ValueTask OpenWriteCoreAsync(CancellationToken cancellationToken) => - default; - - /// - protected override ValueTask WriteCoreAsync(Stream stream, bool overwrite, CancellationToken cancellationToken) => - default; - - /// - protected override ValueTask DeleteCoreAsync(CancellationToken cancellationToken) => - default; -} diff --git a/src/Ramstack.FileSystem.Zip/ZipFileSystem.cs b/src/Ramstack.FileSystem.Zip/ZipFileSystem.cs deleted file mode 100644 index 0754f0e..0000000 --- a/src/Ramstack.FileSystem.Zip/ZipFileSystem.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.IO.Compression; -using System.Runtime.CompilerServices; - -using Ramstack.FileSystem.Null; - -namespace Ramstack.FileSystem.Zip; - -/// -/// Represents a file system backed by a ZIP archive. -/// -/// -/// WARNING: -/// -/// The is not thread-safe and allows reading only one file at a time, as it relies on -/// , which does not support parallel read operations or simultaneous opening of multiple streams. -/// -/// -/// You may use this class only if you can guarantee that: -/// -/// Only one file is open for reading at a time. -/// No file is accessed concurrently. -/// -/// -/// -[Obsolete("Deprecated due to thread safety limitations and parallel file access capabilities.")] -public sealed class ZipFileSystem : IVirtualFileSystem -{ - private readonly ZipArchive _archive; - private readonly Dictionary _directories; - - /// - public bool IsReadOnly => true; - - /// - /// Initializes a new instance of the class - /// using a ZIP archive located at the specified file path. - /// - /// The path to the ZIP archive file. - public ZipFileSystem(string path) - : this(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - } - - /// - /// Initializes a new instance of the class - /// using a stream containing a ZIP archive. - /// - /// The stream containing the ZIP archive. - /// to leave the stream open - /// after the object is disposed; otherwise, . - public ZipFileSystem(Stream stream, bool leaveOpen = false) - : this(new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen)) - { - } - - /// - /// Initializes a new instance of the class - /// using an existing . - /// - /// The instance - /// to use for providing access to ZIP archive content. - public ZipFileSystem(ZipArchive archive) - { - _archive = archive; - _directories = new Dictionary - { - ["/"] = new ZipDirectory(this, "/") - }; - - Initialize(archive, _directories); - } - - /// - public VirtualFile GetFile(string path) => - FindNode(path) as VirtualFile ?? new NotFoundFile(this, path); - - /// - public VirtualDirectory GetDirectory(string path) => - FindNode(path) as VirtualDirectory ?? new NotFoundDirectory(this, path); - - /// - public void Dispose() => - _archive.Dispose(); - - /// - /// Finds a by its path. - /// - /// The path of the node to find. - /// - /// The if found; otherwise, . - /// - private VirtualNode? FindNode(string path) => - _directories.GetValueOrDefault(VirtualPath.Normalize(path)); - - /// - /// Initializes the file system with entries from the specified ZIP archive. - /// - /// The ZIP archive to read entries from. - /// A dictionary to cache the directory and file nodes. - private void Initialize(ZipArchive archive, Dictionary cache) - { - foreach (var entry in archive.Entries) - { - // - // Strip common path prefixes from zip entries to handle archives - // saved with absolute paths. - // - var path = VirtualPath.Normalize( - entry.FullName[GetPrefixLength(entry.FullName)..]); - - if (VirtualPath.HasTrailingSlash(entry.FullName)) - { - GetOrCreateDirectory(path); - continue; - } - - var directory = GetOrCreateDirectory(VirtualPath.GetDirectoryName(path)); - var file = new ZipFile(this, path, entry); - - // - // Archives legitimately may contain entries with identical names, - // so skip if a file with this name has already been added, - // avoiding duplicates in the directory file list. - // - if (cache.TryAdd(path, file)) - directory.RegisterNode(file); - } - - ZipDirectory GetOrCreateDirectory(string path) - { - if (cache.TryGetValue(path, out var di)) - return (ZipDirectory)di; - - di = new ZipDirectory(this, path); - var parent = GetOrCreateDirectory(VirtualPath.GetDirectoryName(path)); - parent.RegisterNode(di); - cache.Add(path, di); - - return (ZipDirectory)di; - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static int GetPrefixLength(string path) - { - // - // Check only well-known prefixes. - // Note: Since entry names can be arbitrary, - // we specifically target only common absolute path patterns. - // - - if (path.StartsWith(@"\\?\UNC\", StringComparison.OrdinalIgnoreCase) - || path.StartsWith(@"\\.\UNC\", StringComparison.OrdinalIgnoreCase) - || path.StartsWith("//?/UNC/", StringComparison.OrdinalIgnoreCase) - || path.StartsWith("//./UNC/", StringComparison.OrdinalIgnoreCase)) - return 8; - - if (path.StartsWith(@"\\?\", StringComparison.Ordinal) - || path.StartsWith(@"\\.\", StringComparison.Ordinal) - || path.StartsWith("//?/", StringComparison.Ordinal) - || path.StartsWith("//./", StringComparison.Ordinal)) - return path.Length >= 6 && IsAsciiLetter(path[4]) && path[5] == ':' ? 6 : 4; - - if (path.Length >= 2 - && IsAsciiLetter(path[0]) && path[1] == ':') - return 2; - - return 0; - - static bool IsAsciiLetter(char ch) => - (uint)((ch | 0x20) - 'a') <= 'z' - 'a'; - } - -} diff --git a/tests/Ramstack.FileSystem.Zip.Tests/Ramstack.FileSystem.Zip.Tests.csproj b/tests/Ramstack.FileSystem.Zip.Tests/Ramstack.FileSystem.Zip.Tests.csproj deleted file mode 100644 index a730740..0000000 --- a/tests/Ramstack.FileSystem.Zip.Tests/Ramstack.FileSystem.Zip.Tests.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net6.0 - enable - enable - preview - Ramstack.FileSystem.Zip - - - - - - - - - - - - - - - - - - - - diff --git a/tests/Ramstack.FileSystem.Zip.Tests/ZipFileSystemTests.cs b/tests/Ramstack.FileSystem.Zip.Tests/ZipFileSystemTests.cs deleted file mode 100644 index 8345e4c..0000000 --- a/tests/Ramstack.FileSystem.Zip.Tests/ZipFileSystemTests.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System.IO.Compression; - -using Ramstack.FileSystem.Specification.Tests; -using Ramstack.FileSystem.Specification.Tests.Utilities; - -#pragma warning disable CS0618 // Type or member is obsolete - -namespace Ramstack.FileSystem.Zip; - -[TestFixture] -public class ZipFileSystemTests : VirtualFileSystemSpecificationTests -{ - private readonly string _path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - private readonly TempFileStorage _storage = new(); - - [OneTimeSetUp] - public void Setup() - { - ZipFile.CreateFromDirectory(_storage.Root, _path, CompressionLevel.Optimal, includeBaseDirectory: false); - } - - [OneTimeTearDown] - public void Cleanup() - { - _storage.Dispose(); - File.Delete(_path); - } - - [Test] - public async Task ZipArchive_WithIdenticalNameEntries() - { - using var fs = new ZipFileSystem(CreateArchive()); - - var list = await fs - .GetFilesAsync("/1") - .ToArrayAsync(); - - Assert.That( - list.Length, - Is.EqualTo(1)); - - Assert.That( - await list[0].ReadAllBytesAsync(), - Is.EquivalentTo("Hello, World!"u8.ToArray())); - - static MemoryStream CreateArchive() - { - var stream = new MemoryStream(); - using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true)) - { - var a = archive.CreateEntry("1/text.txt"); - using (var writer = a.Open()) - writer.Write("Hello, World!"u8); - - archive.CreateEntry("1/text.txt"); - archive.CreateEntry(@"1\text.txt"); - } - - stream.Position = 0; - return stream; - } - } - - [Test] - public async Task ZipArchive_PrefixedEntries() - { - var archive = new ZipArchive(CreateArchive(), ZipArchiveMode.Read, leaveOpen: true); - using var fs = new ZipFileSystem(archive); - - var directories = await fs - .GetDirectoriesAsync("/", "**") - .Select(f => - f.FullName) - .OrderBy(f => f) - .ToArrayAsync(); - - var files = await fs - .GetFilesAsync("/", "**") - .Select(f => - f.FullName) - .OrderBy(f => f) - .ToArrayAsync(); - - Assert.That(files, Is.EquivalentTo( - [ - "/1/text.txt", - "/2/text.txt", - "/3/text.txt", - "/4/text.txt", - "/5/text.txt", - "/localhost/backup/text.txt", - "/localhost/share/text.txt", - "/server/backup/text.txt", - "/server/share/text.txt", - "/text.txt", - "/text.xml" - ])); - - Assert.That(directories, Is.EquivalentTo( - [ - "/1", - "/2", - "/3", - "/4", - "/5", - "/localhost", - "/localhost/backup", - "/localhost/share", - "/server", - "/server/backup", - "/server/share" - ])); - - static MemoryStream CreateArchive() - { - var stream = new MemoryStream(); - using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true)) - { - archive.CreateEntry(@"D:\1/text.txt"); - archive.CreateEntry(@"D:2\text.txt"); - - archive.CreateEntry(@"\\?\D:\text.txt"); - archive.CreateEntry(@"\\?\D:text.xml"); - archive.CreateEntry(@"\\.\D:\3\text.txt"); - archive.CreateEntry(@"//?/D:/4\text.txt"); - archive.CreateEntry(@"//./D:\5/text.txt"); - - archive.CreateEntry(@"\\?\UNC\localhost\share\text.txt"); - archive.CreateEntry(@"\\.\unc\server\share\text.txt"); - archive.CreateEntry(@"//?/UNC/localhost/backup\text.txt"); - archive.CreateEntry(@"//./unc/server/backup\text.txt"); - } - - stream.Position = 0; - return stream; - } - } - - [Test] - public async Task ZipArchive_Directories() - { - using var fs = new ZipFileSystem(CreateArchive()); - - var directories = await fs - .GetDirectoriesAsync("/", "**") - .Select(f => - f.FullName) - .OrderBy(f => f) - .ToArrayAsync(); - - Assert.That(directories, Is.EquivalentTo( - [ - "/1", - "/2", - "/2/3", - "/4", - "/4/5", - "/4/5/6" - ])); - - static MemoryStream CreateArchive() - { - var stream = new MemoryStream(); - using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true)) - { - archive.CreateEntry(@"\1/"); - archive.CreateEntry(@"\2/"); - archive.CreateEntry(@"/2\"); - archive.CreateEntry(@"/2\"); - archive.CreateEntry(@"/2\"); - archive.CreateEntry(@"/2\3/"); - archive.CreateEntry(@"/2\3/"); - archive.CreateEntry(@"/2\3/"); - archive.CreateEntry(@"4\5/6\"); - } - - stream.Position = 0; - return stream; - } - } - - - /// - protected override IVirtualFileSystem GetFileSystem() => - new ZipFileSystem(_path); - - /// - protected override DirectoryInfo GetDirectoryInfo() => - new(_storage.Root); -} From d7a05cd266f4fc0405a8ae7a589f244e102f44df Mon Sep 17 00:00:00 2001 From: rameel Date: Tue, 2 Sep 2025 04:07:49 +0500 Subject: [PATCH 2/2] Update README --- README.md | 1 - src/Ramstack.FileSystem.Abstractions/README.md | 1 - src/Ramstack.FileSystem.Adapters/README.md | 1 - src/Ramstack.FileSystem.Amazon/README.md | 1 - src/Ramstack.FileSystem.Azure/README.md | 1 - src/Ramstack.FileSystem.Composite/README.md | 1 - src/Ramstack.FileSystem.Globbing/README.md | 1 - src/Ramstack.FileSystem.Google/README.md | 1 - src/Ramstack.FileSystem.Physical/README.md | 1 - src/Ramstack.FileSystem.Prefixed/README.md | 1 - src/Ramstack.FileSystem.Readonly/README.md | 1 - src/Ramstack.FileSystem.Sub/README.md | 1 - 12 files changed, 12 deletions(-) diff --git a/README.md b/README.md index 73dcd07..f848d2c 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,6 @@ if (!fs.IsReadOnly) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Abstractions/README.md b/src/Ramstack.FileSystem.Abstractions/README.md index ddf2a0f..0053dcf 100644 --- a/src/Ramstack.FileSystem.Abstractions/README.md +++ b/src/Ramstack.FileSystem.Abstractions/README.md @@ -150,7 +150,6 @@ if (!fs.IsReadOnly) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Adapters/README.md b/src/Ramstack.FileSystem.Adapters/README.md index 3a5cd9a..e724dd7 100644 --- a/src/Ramstack.FileSystem.Adapters/README.md +++ b/src/Ramstack.FileSystem.Adapters/README.md @@ -39,7 +39,6 @@ await foreach (VirtualFile file in fs.GetFilesAsync("/")) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Amazon/README.md b/src/Ramstack.FileSystem.Amazon/README.md index 637e7cc..7847a54 100644 --- a/src/Ramstack.FileSystem.Amazon/README.md +++ b/src/Ramstack.FileSystem.Amazon/README.md @@ -49,7 +49,6 @@ AmazonS3FileSystem fs = new AmazonS3FileSystem( - [Ramstack.FileSystem.Physical](https://www.nuget.org/packages/Ramstack.FileSystem.Physical) - Provides an implementation based on the local file system. - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Azure/README.md b/src/Ramstack.FileSystem.Azure/README.md index 727d9a6..6447bc5 100644 --- a/src/Ramstack.FileSystem.Azure/README.md +++ b/src/Ramstack.FileSystem.Azure/README.md @@ -41,7 +41,6 @@ AzureFileSystem fs = new AzureFileSystem(connectionString, containerName: "stora - [Ramstack.FileSystem.Physical](https://www.nuget.org/packages/Ramstack.FileSystem.Physical) - Provides an implementation based on the local file system. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Composite/README.md b/src/Ramstack.FileSystem.Composite/README.md index 371cfdf..7bee73a 100644 --- a/src/Ramstack.FileSystem.Composite/README.md +++ b/src/Ramstack.FileSystem.Composite/README.md @@ -33,7 +33,6 @@ await foreach (VirtualFile file in fs.GetFilesAsync("/")) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Globbing/README.md b/src/Ramstack.FileSystem.Globbing/README.md index 9d30996..5b87f52 100644 --- a/src/Ramstack.FileSystem.Globbing/README.md +++ b/src/Ramstack.FileSystem.Globbing/README.md @@ -38,7 +38,6 @@ await foreach (VirtualFile file in fs.GetFilesAsync("/")) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. - [Ramstack.FileSystem.Sub](https://www.nuget.org/packages/Ramstack.FileSystem.Sub) - Wraps the underlying file system, restricting access to a specific subpath. diff --git a/src/Ramstack.FileSystem.Google/README.md b/src/Ramstack.FileSystem.Google/README.md index a7aff67..e723209 100644 --- a/src/Ramstack.FileSystem.Google/README.md +++ b/src/Ramstack.FileSystem.Google/README.md @@ -44,7 +44,6 @@ GoogleFileSystem fs = new GoogleFileSystem(client, bucketName: "my-bucket") - [Ramstack.FileSystem.Physical](https://www.nuget.org/packages/Ramstack.FileSystem.Physical) - Provides an implementation based on the local file system. - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Physical/README.md b/src/Ramstack.FileSystem.Physical/README.md index 4f56c65..17e754a 100644 --- a/src/Ramstack.FileSystem.Physical/README.md +++ b/src/Ramstack.FileSystem.Physical/README.md @@ -39,7 +39,6 @@ PhysicalFileSystem fs = new PhysicalFileSystem(@"C:\path\to\directory") - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. diff --git a/src/Ramstack.FileSystem.Prefixed/README.md b/src/Ramstack.FileSystem.Prefixed/README.md index cdb5b11..4ba1dbe 100644 --- a/src/Ramstack.FileSystem.Prefixed/README.md +++ b/src/Ramstack.FileSystem.Prefixed/README.md @@ -37,7 +37,6 @@ await foreach (VirtualFile file in fs.GetFilesAsync("/public/assets")) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Sub](https://www.nuget.org/packages/Ramstack.FileSystem.Sub) - Wraps the underlying file system, restricting access to a specific subpath. diff --git a/src/Ramstack.FileSystem.Readonly/README.md b/src/Ramstack.FileSystem.Readonly/README.md index 475a6bc..03dd040 100644 --- a/src/Ramstack.FileSystem.Readonly/README.md +++ b/src/Ramstack.FileSystem.Readonly/README.md @@ -34,7 +34,6 @@ await fs.DeleteFileAsync("/hello.txt"); - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system. - [Ramstack.FileSystem.Sub](https://www.nuget.org/packages/Ramstack.FileSystem.Sub) - Wraps the underlying file system, restricting access to a specific subpath. diff --git a/src/Ramstack.FileSystem.Sub/README.md b/src/Ramstack.FileSystem.Sub/README.md index 35cbff2..b563193 100644 --- a/src/Ramstack.FileSystem.Sub/README.md +++ b/src/Ramstack.FileSystem.Sub/README.md @@ -34,7 +34,6 @@ await foreach (VirtualFile file in fs.GetFilesAsync("/")) - [Ramstack.FileSystem.Azure](https://www.nuget.org/packages/Ramstack.FileSystem.Azure) - Provides an implementation using Azure Blob storage. - [Ramstack.FileSystem.Amazon](https://www.nuget.org/packages/Ramstack.FileSystem.Amazon) - Provides an implementation using Amazon S3 storage. - [Ramstack.FileSystem.Google](https://www.nuget.org/packages/Ramstack.FileSystem.Google) - Provides an implementation using Google Cloud storage. -- [Ramstack.FileSystem.Zip](https://www.nuget.org/packages/Ramstack.FileSystem.Zip) - Provides an implementation based on ZIP archives. - [Ramstack.FileSystem.Readonly](https://www.nuget.org/packages/Ramstack.FileSystem.Readonly) - Provides a read-only wrapper for the underlying file system. - [Ramstack.FileSystem.Globbing](https://www.nuget.org/packages/Ramstack.FileSystem.Globbing) - Wraps the file system, filtering files and directories using glob patterns. - [Ramstack.FileSystem.Prefixed](https://www.nuget.org/packages/Ramstack.FileSystem.Prefixed) - Adds a prefix to file paths within the underlying file system.