![]() |
VOOZH | about |
dotnet add package Gapotchenko.FX.IO --version 2026.7.2
NuGet\Install-Package Gapotchenko.FX.IO -Version 2026.7.2
<PackageReference Include="Gapotchenko.FX.IO" Version="2026.7.2" />
<PackageVersion Include="Gapotchenko.FX.IO" Version="2026.7.2" />Directory.Packages.props
<PackageReference Include="Gapotchenko.FX.IO" />Project file
paket add Gapotchenko.FX.IO --version 2026.7.2
#r "nuget: Gapotchenko.FX.IO, 2026.7.2"
#:package Gapotchenko.FX.IO@2026.7.2
#addin nuget:?package=Gapotchenko.FX.IO&version=2026.7.2Install as a Cake Addin
#tool nuget:?package=Gapotchenko.FX.IO&version=2026.7.2Install as a Cake Tool
The module provides commonly demanded input/output functionality that is missing in baseline .NET platform.
FileSystem is a class provided by Gapotchenko.FX.IO module.
If offers extended I/O functions for file system,
and serves as an important addendum to a conventional System.IO namespace.
The FileSystem.IsCaseSensitive property shows whether the current host operating system uses case sensitive file names.
For example, Windows operating system uses case-insensitive file names,
so FileSystem.IsCaseSensitive returns false.
The same goes to macOS.
However, Linux and other Unix flavors use case-sensitive file names by default.
Whenever an app creates two files named Test.txt and test.txt,
those files are distinct and can coexist at the same folder.
FileSystem.IsCaseSensitive returns true on such operating systems.
FileSystem.PathComparer property returns a string comparer for file names.
Please take a look at the code below:
using Gapotchenko.FX.IO;
var files = new HashSet<string>(FileSystem.PathComparer);
files.Add("Test.txt");
files.Add("test.txt");
Console.WriteLine("Count of files: {0}", files.Count);
The given set would contain one entry on Windows, and two entries on Linux.
FileSystem.PathComparison property returns a StringComparison value that signifies a file name comparison mode used by the host OS.
It can be used in string comparison operations:
using Gapotchenko.FX.IO;
void ProcessFile(string filePath)
{
if (!filePath.EndsWith(".txt", FileSystem.PathComparison))
throw new Exception("Only text files can be processed.");
…
}
Determines whether the given paths are equivalent. If they point to the same file system entry then the method returns true; otherwise, false.
The problem this method solves is caused by the fact that a file path can be specified in multiple forms:
Test.txt (relative path)C:\Temp\Test.txt (absolute path)Let's take a look at code:
using Gapotchenko.FX.IO;
Directory.SetCurrentDirectory(@"C:\Temp");
string fileA = "Test.txt";
string fileB = @"C:\Temp\Test.txt";
Console.WriteLine("String equality: {0}", string.Equals(fileA, fileB));
Console.WriteLine("Path equivalence: {0}", FileSystem.PathsAreEquivalent(fileA, fileB));
It produces the following results:
String equality: False
Path equivalence: True
Note that the file equivalence check is positive despite the different forms of a file path.
Determines whether the beginning of the path matches the specified value in terms of the file system equivalence.
Say we have a folder name Contoso\Reports\2012\Final.
How do we know that it starts with Contoso\Reports?
A straightforward solution would be to use String.StartsWith function, like so:
bool IsContosoReportsFolder(string path) => path.StartsWith(@"Contoso\Reports");
It kind of works, until we try to pass something like Contoso\ReportsBackup.
The problem is that ReportsBackup is a very different folder than Reports, but the provided function returns true nevertheless.
We can cheat here, and try to use an updated function that adds a trailing slash:
bool IsContosoReportsFolder(string path) => path.StartsWith(@"Contoso\Reports\");
The problem is gone.
Until we ask for IsContosoReportsFolder("Contoso\Reports") value.
It is false now despite the fact that Contoso\Reports is literally the folder we are so eagerly looking for.
The correct solution is to use FileSystem.PathStartsWith method provided by Gapotchenko.FX.IO module:
using Gapotchenko.FX.IO;
bool IsContosoReportsFolder(string path) => FileSystem.PathStartsWith(path, @"Contoso\Reports");
It will now give the correct results for all inputs, even when they use alternative directory separators:
IsContosoReportsFolder(@"Contoso\ReportsBackup") => false
IsContosoReportsFolder(@"Contoso\Reports\2012\Final") => true
IsContosoReportsFolder(@"Contoso\Reports") => true
IsContosoReportsFolder(@"Contoso/Reports/2019/Progress") => true
FileSystem.WaitForFileWriteAccess method is a subtle but important primitive. It waits for a write access to the specified file.
Why would anyone want such a method? It turns out that a modern OS is a noisy environment that can put your app under a sledgehammer.
For example, if an app changes a file, it immediately grabs attention of various OS services. Anti-virus tools, search engines, file synchronization applications, all can lock the files for short and random time spans.
If a user of your app is unlucky or just uses an app frequently enough then he would occasionally get "File access denied" errors.
To minimize a possibility of such a congestion, you can call FileSystem.WaitForFileWriteAccess method before changing a file:
using Gapotchenko.FX.IO;
string fileName = "Results.txt";
FileSystem.WaitForFileWriteAccess(fileName);
File.WriteAllText(fileName, "A user can now use the app without occasional 'File access denied' errors.");
What it does is polls the file until write access is available. If the access is not there for 10 seconds, the method falls through.
More on this topic (Raymond Chen, "The Old New Thing" blog)
FileSystem.GetRealPath(string) method gets a canonicalized absolute path of the specified file system entry.
The method expands all symbolic links and resolves references to . and .. special directories.
It also normalizes consequent directory separators to the canonical form.
BitReader and BitWriter classes provided by Gapotchenko.FX.IO extend the functionality of conventional BinaryReader and BinaryWriter by inheriting from them.
The conventional BinaryReader/BinaryWriter combo only supports little-endian byte order.
However, big-endian byte order is equally widespread.
This is how a big-endian binary reader can be created:
using Gapotchenko.FX;
using Gapotchenko.FX.IO;
var br = new BitReader(BigEndianBitConverter.Instance);
Thanks to the fact that BitReader is inherited from BinaryReader class, it is almost a drop-in replacement.
The same goes to BitWriter.
Gapotchenko.FX.IO.FileSystemGapotchenko.FX.IO.BitReaderGapotchenko.FX.IO.BitWriterLet's continue with a look at some other modules provided by Gapotchenko.FX:
Or look at the full list of modules.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net6.0-windows7.0 net6.0-windows7.0 is compatible. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net7.0-windows7.0 net7.0-windows7.0 is compatible. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net8.0-windows7.0 net8.0-windows7.0 is compatible. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net9.0-windows7.0 net9.0-windows7.0 is compatible. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. net10.0-windows7.0 net10.0-windows7.0 is compatible. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 is compatible. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 is compatible. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Gapotchenko.FX.IO:
| Package | Downloads |
|---|---|
|
Gapotchenko.FX.Diagnostics.CommandLine
Provides primitives for command line manipulation. |
|
|
Gapotchenko.FX.Profiles.Core
Represents the Core profile of Gapotchenko.FX toolkit. |
|
|
Gapotchenko.FX.IO.Vfs
Provides a virtual file system (VFS) abstraction layer that enables uniform access to different file storage backends, including local file systems, archives, and custom storage formats. |
|
|
Gapotchenko.Shields.MSys2.Deployment
The deployment module of MSYS2 Shield. |
|
|
Gapotchenko.Shields.Cygwin.Deployment
The deployment module of Cygwin Shield. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.7.2 | 4,394 | 5/16/2026 |
| 2026.6.2 | 6,175 | 3/29/2026 |
| 2026.5.3 | 383 | 2/24/2026 |
| 2026.4.2 | 360 | 2/4/2026 |
| 2026.3.5 | 366 | 1/29/2026 |
| 2026.2.2 | 361 | 1/25/2026 |
| 2026.1.5 | 386 | 1/13/2026 |
| 2025.1.45 | 707 | 12/25/2025 |
| 2025.1.27-beta | 436 | 10/8/2025 |
| 2025.1.26-beta | 488 | 8/30/2025 |
| 2025.1.25-beta | 1,132 | 7/22/2025 |
| 2025.1.24-beta | 651 | 7/16/2025 |
| 2025.1.23-beta | 606 | 7/12/2025 |
| 2024.2.5 | 403 | 12/31/2024 |
| 2024.1.3 | 339 | 11/10/2024 |
| 2022.2.7 | 1,040 | 5/1/2022 |
| 2022.2.5 | 991 | 5/1/2022 |
| 2022.1.4 | 955 | 4/6/2022 |
| 2021.2.21 | 1,056 | 1/21/2022 |