C# file/folder helpers

There are times when the working with files and folders a developer runs into unusual task that for some may be difficult to figure out or takes too much time to code.

Bookmark this article for methods for working with files and folders and overtime m…


This content originally appeared on DEV Community and was authored by Karen Payne

There are times when the working with files and folders a developer runs into unusual task that for some may be difficult to figure out or takes too much time to code.

Bookmark this article for methods for working with files and folders and overtime more code samples will be added as there are many more to come. What will not be added are methods easy to find on the Internet.

Requires

  • Microsoft Visual Studio 2022 or higher
  • .NET Core 7 or higher

Is folder or file

When traversing a folder a developer may want to know if an item is a file or folder.

The following method will, if successful indicate if an item is a file or folder and if the item does not exists the method returns false.

public static (bool isFolder, bool success) IsFileOrFolder(string path)
{
    try
    {
        var attr = File.GetAttributes(path);
        return attr.HasFlag(FileAttributes.Directory) ? (true, true)! : (false, true)!;
    }
    catch (FileNotFoundException)
    {
        return (false, false);
    }
}

In the following example, LogFile folder exists, its created using a msbuild task, Log does not exists but TextFile1.txt does exists.

static void Main(string[] args)
{
    var items = new List<string>
    {
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LogFiles"),
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log"),
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TextFile1.txt")
    };

    foreach (var item in items)
    {
        var (isFolder, success) = FileHelpers.IsFileOrFolder(item);
        if (success)
        {
            AnsiConsole.MarkupLine($"{item}");
            AnsiConsole.MarkupLine($"\tIs folder {isFolder}");
        }
        else
        {
            AnsiConsole.MarkupLine($"[white]{item}[/] [red]not found[/]");
        }
    }

    Console.ReadLine();
}

Is file locked

The following method detects if a file is locked when a file is opened with the attribute FileShare.None. Typical example, a developer does not close an Excel file properly or has the Excel file open outside the project.

This will not work if a file is open in shared mode.

public static async Task<bool> CanReadFile(string fileName)
{
    static bool IsFileLocked(Exception exception)
    {
        var errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
        return errorCode is ErrorSharingViolation or ErrorLockViolation;
    }

    try
    {
        await using var fileStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        if (fileStream != null)
        {
            fileStream.Close();
        }
    }
    catch (IOException ex)
    {
        if (IsFileLocked(ex))
        {
            return false;
        }
    }

    await Task.Delay(50);

    return true;

}

See the project IsFileLockedSample for an interactive example with an Excel file and a text file.

Natural sort file names

The following methods will sort file names that end in numbers or an array or list with strings ending in numbers the same as in Windows Explorer.

public class NaturalStringComparer : Comparer<string>
{

    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string x, string y);

    public override int Compare(string x, string y)
        => StrCmpLogicalW(x, y);
}

Example with a list of unsorted strings.

using System.Runtime.CompilerServices;
using Spectre.Console;
using static HelperLibrary.FileHelpers;

namespace NaturalSortSample;

internal class Program
{
    static void Main(string[] args)
    {
        StandardSortSample();
        NaturalSortSample();
        Console.ReadLine();
    }

    private static void NaturalSortSample()
    {
        Print("Natural sort");
        var fileNames = FileNames();

        fileNames.Sort(new NaturalStringComparer());

        foreach (var item in fileNames)
        {
            Console.WriteLine(item);
        }

    }
    private static void StandardSortSample()
    {
        Print("Standard sort");
        var fileNames = FileNames();

        foreach (var item in fileNames)
        {
            Console.WriteLine(item);
        }


    }

    private static List<string> FileNames() =>
        new()
        {
            "Example12.txt", "Example2.txt", "Example3.txt", "Example4.txt",
            "Example5.txt", "Example6.txt", "Example7.txt", "Example8.txt",
            "Example9.txt", "Example10.txt", "Example11.txt", "Example1.txt",
            "Example13.txt", "Example14.txt", "Example15.txt", "Example16.txt",
            "Example17.txt", "Example18.txt", "Example19.txt", "Example20.txt"
        };

    private static void Print(string text)
    {
        AnsiConsole.MarkupLine($"[yellow]{text}[/]");
    }

    [ModuleInitializer]
    public static void Init()
    {
        Console.Title = "Code sample";
        W.SetConsoleWindowPosition(W.AnchorWindow.Center);
    }
}

Globbing

File globbing can in specific cases allow a developer to fine tune files that are looking for in a folder or folders.

Provides

  • Inclusion of files via patterns
  • Exclusion of file via patterns

Base patterns

Value Description
*.txt All files with .txt file extension.
*.* All files with an extension
* All files in top-level directory.
.* File names beginning with '.'.
*word* All files with 'word' in the filename.
readme.* All files named 'readme' with any file extension.
styles/*.css All files with extension '.css' in the directory 'styles/'.
scripts/*/* All files in 'scripts/' or one level of subdirectory under 'scripts/'.
images*/* All files in a folder with name that is or begins with 'images'.
**/* All files in any subdirectory.
dir/**/* All files in any subdirectory under 'dir/'.
../shared/* All files in a diretory named "shared" at the sibling level to the base directory

In this project (Razor Pages) the goal is to get all .cs file with several exclusions as per the variable exclude

await GlobbingOperations.Find(path, include, exclude); traverses the path which in this case is the current solution folder and on a match adds the match to a StringBuilder which we return the page and append to the body of the page the results.

public class IndexModel : PageModel
{
    public IndexModel()
    {
        GlobbingOperations.TraverseFileMatch += TraverseFileMatch;
    }

    [BindProperty]
    public StringBuilder Builder { get; set; } = new();
    public void OnGet()
    {

    }

    public async Task<PageResult> OnPost()
    {
        string path = DirectoryHelper.SolutionFolder();

        string[] include = { "**/*.cs", "**/*.cshtml" };
        string[] exclude =
        {
            "**/*Assembly*.cs",
            "**/*_*.cshtml",
            "**/*Designer*.cs",
            "**/*.g.i.cs",
            "**/*.g.cs",
            "**/TemporaryGeneratedFile*.cs"
        };

        Builder = new StringBuilder();
        await GlobbingOperations.Find(path, include, exclude);
        return Page();
    }

    private void TraverseFileMatch(FileMatchItem sender)
    {
        Log.Information(Path.Combine(sender.Folder, sender.FileName));
        Builder.AppendLine(Path.Combine(sender.Folder, sender.FileName));
    }
}

Stay tune for more

More useful methods will be added over time.

Source code

Clone the following GitHub repository.


This content originally appeared on DEV Community and was authored by Karen Payne


Print Share Comment Cite Upload Translate Updates
APA

Karen Payne | Sciencx (2023-04-30T01:49:18+00:00) C# file/folder helpers. Retrieved from https://www.scien.cx/2023/04/30/c-file-folder-helpers/

MLA
" » C# file/folder helpers." Karen Payne | Sciencx - Sunday April 30, 2023, https://www.scien.cx/2023/04/30/c-file-folder-helpers/
HARVARD
Karen Payne | Sciencx Sunday April 30, 2023 » C# file/folder helpers., viewed ,<https://www.scien.cx/2023/04/30/c-file-folder-helpers/>
VANCOUVER
Karen Payne | Sciencx - » C# file/folder helpers. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/04/30/c-file-folder-helpers/
CHICAGO
" » C# file/folder helpers." Karen Payne | Sciencx - Accessed . https://www.scien.cx/2023/04/30/c-file-folder-helpers/
IEEE
" » C# file/folder helpers." Karen Payne | Sciencx [Online]. Available: https://www.scien.cx/2023/04/30/c-file-folder-helpers/. [Accessed: ]
rf:citation
» C# file/folder helpers | Karen Payne | Sciencx | https://www.scien.cx/2023/04/30/c-file-folder-helpers/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.