FileCurator 5.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package FileCurator --version 5.0.0                
NuGet\Install-Package FileCurator -Version 5.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FileCurator" Version="5.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FileCurator --version 5.0.0                
#r "nuget: FileCurator, 5.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FileCurator as a Cake Addin
#addin nuget:?package=FileCurator&version=5.0.0

// Install FileCurator as a Cake Tool
#tool nuget:?package=FileCurator&version=5.0.0                

FileCurator

.NET Publish

FileCurator is a library used to simplify file access and management on your system. It aims to make accessing a local file as simple as accessing a URL or 3rd party system like Dropbox.

Basic Usage

The system relies on your app's ServiceCollection in order to wire itself up correctly. In order to use the system you need to add the following line to your application's startup code:

services.RegisterFileCurator();

Or if you're using Canister:

services.AddCanisterModules();

This line is required prior to using the extension methods, FileInfo, and DirectoryInfo classes for the first time. Once it is set up, you can call the classes provided:

var MyFile = new FileInfo("~/MyFile.txt");
MyFile = new FileInfo("./MyFile.txt");
MyFile = new FileInfo("MyFile.txt");
MyFile = new FileInfo("http://www.google.com");
MyFile = new FileInfo("resource://MyDLL/MyDLL.Resources.MyFile.txt");

The FileInfo and DirectoryInfo classes take a string for the file path as well as a user name, password, and domain, assuming the file system you are trying to reach requires it. It translates ~ and . to be the local base directory. From there you will have access to the file's contents and information. Similarly you can pass in web addresses or the location of embedded resource files and will be able to read them accordingly.

Embedded Resources

For embedded resources, the syntax is:

resource://MyDLL/MyDLL.Resources.Directory.MyFile.txt

Where resource:// lets the system know you want to retrieve an embedded resource. MyDLL is the name of the Assembly that the resource is found in. And MyFile.txt is the name of the file. Depending on where you placed the file the path inside the project will be the Resources.Directory portion of the above example. In the above case it was placed in the /Resources/Directory folder inside the assembly. Instead of slashes the system separates them with a period instead. If you placed the resources at the base of the project, then the Resouces.Directory portion can be left out and it would just be:

resource://MyDLL/MyDLL.MyFile.txt

Adding File Systems

The system comes with a couple of built in file systems for dealing with local files, however you may wish to add other targets as well. In order to do this all that you need to do is create a class that inherits from IFileSystem, a class that inherits from IFile, and one for IDirectory. From there the system will find the new provider and use it when called.

Overriding File Systems

By default the system comes with a couple of file systems for dealing with local files. However it is possible to override these by simply creating a class that inherits from IFileSystem and setting the correct Name to match the one that you wish to override. There is a base class called LocalFileSystemBase that can help with most of the functions for the file system as well. For instance to override the "Relative Local" system with your own you would do the following:

public class MyLocalFileSystem : LocalFileSystemBase
{
    /// <summary>
    /// Name of the file system
    /// </summary>
    public override string Name { get { return "Relative Local"; } }

    /// <summary>
    /// Relative starter
    /// </summary>
    protected override string HandleRegexString { get { return @"^[~|\.]"; } }

    /// <summary>
    /// Gets the absolute path of the variable passed in
    /// </summary>
    /// <param name="path">Path to convert to absolute</param>
    /// <returns>The absolute path of the path passed in</returns>
    protected override string AbsolutePath(string path)
    {
        ...
    }
}

From there the system will override the default "Relative Local" provider with your own.

Parsing Files

FileCurator also has a number of file formats that it understands and can parse:

  • CSV
  • TSV
  • Tab delimited
  • Excel (XLSX files only)
  • HTML files
  • ICS (iCalendar files)
  • EML
  • MHT
  • PowerPoint (PPTX and PPSX)
  • RSS
  • VCS (vCal files)
  • VCF (vCard files)
  • Word (DOCX files only)
  • XML
  • PDF
  • MSG files
  • And of course TXT files

In order to parse a file you would do the following:

var MyFile = new FileInfo("~/MyFile.txt").Parse();

The above code opens the MyFile.txt document and parses it into a IGenericFile object. This object contains a Content property, a Title property, and a Meta property. For the above text file, only the Content property is filled in. However you can also do this:

var MyEmail = new FileInfo("~/MyEmail.eml").Parse();

This will take the content of the email and place it in the Content property, the subject of the email is in Title. However you may be saying, what about To, or BCC, or From fields? That's why there is another Parse method:

var MyEmail = new FileInfo("~/MyEmail.eml").Parse<IMessage>();

This time we get back an IMessage object instead of an IGenericFile object. And the IMessage object has fields for To, BCC, CC, From, Sent date, etc. The Parse<>() method takes any type that inherits from IGenericFile. The built in types are:

  • IMessage
  • ITable
  • IFeed
  • ICard
  • ICalendar

And each of these correspond to a particular set of file formats:

  • IMessage - EML, MHT, and MSG files.
  • ITable - Delimited (CSV, TSV, etc.) and Excel files.
  • IFeed - RSS files.
  • ICard - vCards
  • ICalendar - iCal and vCal files.

All other file types are parsed as IGenericFile objects. And calling for an object of type A when the parser returns type B will throw an exception. So if you have no idea what the file is, it's best to just use the Parse() method instead.

Writing an object to a file is similarly simple:

var MyTable = new GenericTable();
MyTable.Columns.Add("Column Header 1");
MyTable.Columns.Add("Column Header 2");
MyTable.Rows.Add(new GenericRow());
MyTable.Rows[0].Cells.Add(new GenericCell("My Data"));
MyTable.Rows[0].Cells.Add(new GenericCell("Goes Here"));
new FileInfo("~/MyFile.xlsx").Write(MyTable);

The above code creates a table object with 2 column headers and a single row containing two cells, the first contains "My Data" and the second contains "Goes Here". The FileInfo object then takes the extension of the file that you are saving to and sends it to the proper format handler for writing the data to disk. In the above case it would be the Excel handler. You can similarly take the ITable object and save it as a CSV:

new FileInfo("~/MyFile.csv").Write(MyTable);

No other code needs to change, just the file extension and it saves it properly as a CSV.

There are also extension methods to work with Streams instead of just FileInfo objects:

using(var TempStream = new MemoryStream())
{
    TempStream.Write(new GenericFile("This is my content","My Title",""), MimeType.Word);
}

The above code would write to the TempStream object a word doc that contains "This is my content" in the body and have a title of "My Title". You can similarly parse Stream objects like the FileInfo object but the only difference is that it takes in a MimeType object. This is to help it figure out what sort of file is in the stream. However for unknown files you can specify MimeType.Unknown. The system will then try its best to figure out what the file is and act accordingly.

Writing Your Own Format Parser

All format parsers must inherit from the IFormat<TFile> interface. However there is a base class to help simplify some of the process called FormatBaseClass<TFileReader, TFileWriter, TFile>, but it is not required. As an example:

/// <summary>
/// Text format
/// </summary>
/// <seealso cref="BaseClasses.FormatBaseClass{TxtReader, TxtWriter, IGenericFile}"/>
public class TxtFormat : FormatBaseClass<TxtReader, TxtWriter, IGenericFile>
{
    /// <summary>
    /// Gets the content types.
    /// </summary>
    /// <value>The content types.</value>
    public override string[] ContentTypes => new[] { "TEXT/PLAIN" };

    /// <summary>
    /// Gets or sets the display name.
    /// </summary>
    /// <value>The display name.</value>
    public override string DisplayName => "Text";

    /// <summary>
    /// Gets or sets the file types.
    /// </summary>
    /// <value>The file types.</value>
    public override string[] FileTypes => new[] { "TXT" };
}

The above class is the TXT file parser. It also has a reader class:

/// <summary>
/// TXT file reader
/// </summary>
/// <seealso cref="Interfaces.IGenericFileReader{IGenericFile}"/>
public class TxtReader : ReaderBaseClass<IGenericFile>
{
    /// <summary>
    /// Gets the header identifier.
    /// </summary>
    /// <value>The header identifier.</value>
    public override byte[] HeaderIdentifier => new byte[0];

    /// <summary>
    /// Reads the specified stream.
    /// </summary>
    /// <param name="stream">The stream.</param>
    /// <returns>The file</returns>
    public override IGenericFile Read(Stream stream)
    {
        return new GenericFile(stream.ReadAll(), "", "");
    }
}

And a writer class:

/// <summary>
/// Txt Writer
/// </summary>
/// <seealso cref="IGenericFileWriter"/>
public class TxtWriter : IGenericFileWriter
{
    /// <summary>
    /// Writes the file to the specified writer.
    /// </summary>
    /// <param name="writer">The writer.</param>
    /// <param name="file">The file.</param>
    /// <returns>True if it writes successfully, false otherwise.</returns>
    public bool Write(Stream writer, IGenericFile file)
    {
        var TempData = Encoding.UTF8.GetBytes(file.ToString());
        writer.Write(TempData, 0, TempData.Length);
        return true;
    }
}

You can create something similar for your formats as well. From there the system will automatically pick up your format and use it when appropriate. You can also override the existing formats with your own. You just need to state the content type and file types that you wish to intercept and it will use your items instead of the corresponding items in FileCurator.

Installation

The library is available via Nuget with the package name "FileCurator". To install it run the following command in the Package Manager Console:

Install-Package FileCurator

Build Process

In order to build the library you will require the following as a minimum:

  1. Visual Studio 2022

Other than that, just clone the project and you should be able to load the solution and build without too much effort.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on FileCurator:

Package Downloads
Mecha.Core

Mecha is a C# library that enables automatic testing of classes with the goal of finding ways to break the code. It provides various testing capabilities such as unit testing, security testing through data fuzzing, checking for concurrency issues, and verifying fault tolerance. With just a single line of code, Mecha can automatically test every method in a class. The library seamlessly integrates with your existing testing framework.

TaskMaster

TaskMaster is a simple library used to manage sets of fire and forget tasks that need to run after specific dates/times.

Spidey

Spidey is a library designed to help with crawling and parsing web content.

TestFountain

TestFountain is a set of addons/extensions for xUnit.net to help with things like data generation.

Enlighten

Enlighten is a set of tools to help with natural language processing.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
5.0.1 831 12/9/2024
5.0.0 1,037 11/24/2024
4.1.13 1,256 11/12/2024
4.1.12 522 11/11/2024
4.1.11 878 11/5/2024
4.1.10 418 11/4/2024
4.1.9 687 10/30/2024
4.1.8 373 10/29/2024
4.1.7 156 10/29/2024
4.1.6 1,914 10/10/2024
4.1.5 417 10/9/2024
4.1.4 383 10/8/2024
4.1.3 628 10/1/2024
4.1.2 446 9/30/2024
4.1.1 1,075 9/23/2024
4.1.0 676 9/16/2024
4.0.110 710 9/9/2024
4.0.109 869 9/2/2024
4.0.108 491 8/29/2024
4.0.107 699 8/26/2024
4.0.106 510 8/23/2024
4.0.105 446 8/22/2024
4.0.104 971 8/20/2024
4.0.103 403 8/19/2024
4.0.102 556 8/15/2024
4.0.101 447 8/14/2024
4.0.100 894 8/2/2024
4.0.99 287 8/1/2024
4.0.98 379 7/31/2024
4.0.97 614 7/25/2024
4.0.96 1,112 7/10/2024
4.0.95 1,079 7/1/2024
4.0.94 766 6/26/2024
4.0.93 423 6/25/2024
4.0.92 1,167 6/18/2024
4.0.91 411 6/17/2024
4.0.90 452 6/14/2024
4.0.89 446 6/13/2024
4.0.88 417 6/12/2024
4.0.87 1,156 5/30/2024
4.0.86 390 5/29/2024
4.0.85 998 5/20/2024
4.0.84 530 5/16/2024
4.0.83 373 5/15/2024
4.0.82 976 5/7/2024
4.0.81 426 5/6/2024
4.0.80 702 5/2/2024
4.0.79 301 5/1/2024
4.0.78 346 4/30/2024
4.0.77 492 4/29/2024
4.0.76 975 4/15/2024
4.0.75 645 4/11/2024
4.0.74 428 4/10/2024
4.0.73 1,041 3/29/2024
4.0.72 575 3/28/2024
4.0.71 1,041 3/15/2024
4.0.70 404 3/14/2024
4.0.69 442 3/13/2024
4.0.68 778 3/8/2024
4.0.67 281 3/7/2024
4.0.66 172 3/6/2024
4.0.65 220 3/5/2024
4.0.64 246 3/4/2024
4.0.63 557 2/28/2024
4.0.62 1,573 2/27/2024
4.0.61 535 2/23/2024
4.0.60 188 2/22/2024
4.0.59 228 2/21/2024
4.0.58 561 2/20/2024
4.0.57 585 2/15/2024
4.0.56 246 2/14/2024
4.0.55 324 2/9/2024
4.0.54 361 2/7/2024
4.0.53 234 2/6/2024
4.0.52 2,453 2/5/2024
4.0.51 1,645 1/31/2024
4.0.50 323 1/30/2024
4.0.49 375 1/29/2024
4.0.48 572 1/23/2024
4.0.47 736 1/22/2024
4.0.46 622 1/11/2024
4.0.45 777 1/10/2024
4.0.44 1,382 12/25/2023
4.0.43 717 12/21/2023
4.0.42 696 12/14/2023
4.0.41 337 12/13/2023
4.0.40 354 12/12/2023
4.0.39 2,196 11/23/2023
4.0.38 626 11/20/2023
4.0.37 706 11/17/2023
4.0.36 295 11/16/2023
4.0.35 784 11/13/2023
4.0.34 726 11/7/2023
4.0.33 388 11/6/2023
4.0.32 955 10/31/2023
4.0.31 410 10/30/2023
4.0.30 807 10/25/2023
4.0.29 933 10/11/2023
4.0.28 577 10/4/2023
4.0.27 523 9/25/2023
4.0.26 728 9/19/2023
4.0.25 291 9/18/2023
4.0.24 905 9/13/2023
4.0.23 428 9/12/2023
4.0.22 496 9/11/2023
4.0.21 948 9/6/2023
4.0.20 449 9/5/2023
4.0.19 435 9/4/2023
4.0.18 556 9/1/2023
4.0.17 441 8/31/2023
4.0.16 460 8/30/2023
4.0.15 539 8/29/2023
4.0.14 507 8/28/2023
4.0.13 690 8/24/2023
4.0.12 652 8/22/2023
4.0.11 699 8/17/2023
4.0.10 2,027 8/9/2023
4.0.9 583 8/8/2023
4.0.8 466 8/7/2023
4.0.7 933 8/2/2023
4.0.6 670 7/25/2023
4.0.5 524 7/19/2023
4.0.4 589 7/14/2023
4.0.3 202 7/13/2023
4.0.2 183 7/11/2023
4.0.1 428 12/13/2022
4.0.0 2,208 12/12/2022
3.1.46 1,620 8/15/2022
3.1.45 817 7/6/2022
3.1.44 2,959 6/6/2022
3.1.42 616 5/26/2022
3.1.41 1,182 1/20/2022
3.1.40 4,702 1/11/2022
3.1.39 725 1/10/2022
3.1.37 989 8/25/2021
3.1.36 1,496 7/19/2021
3.1.35 496 7/12/2021
3.1.34 895 6/15/2021
3.1.33 517 5/21/2021
3.1.31 482 5/20/2021
3.1.30 444 5/20/2021
3.1.29 2,495 4/30/2021
3.1.28 4,132 3/12/2021
3.1.27 546 3/11/2021
3.1.26 456 2/20/2021
3.1.25 1,940 1/6/2021
3.1.24 535 1/6/2021
3.1.23 549 12/15/2020
3.1.21 580 12/2/2020
3.1.20 606 9/17/2020
3.1.19 614 9/16/2020
3.1.18 566 9/16/2020
3.1.17 2,071 9/13/2020
3.1.16 1,381 7/29/2020
3.1.15 598 7/29/2020
3.1.14 621 7/16/2020
3.1.13 931 6/7/2020
3.1.12 699 6/7/2020
3.1.11 647 5/5/2020
3.1.10 663 4/30/2020
3.1.9 660 4/30/2020
3.1.8 1,749 4/28/2020
3.1.7 584 4/28/2020
3.1.6 1,261 4/10/2020
3.1.5 2,714 3/25/2020
3.1.4 856 3/25/2020
3.1.3 1,544 3/19/2020
3.1.2 2,237 3/1/2020
3.0.1 720 3/1/2020
3.0.0 5,097 12/23/2019
2.0.17 947 9/26/2019
2.0.16 1,239 4/17/2019
2.0.15 1,172 4/16/2019
2.0.14 4,060 2/21/2019
2.0.13 1,019 1/18/2019
2.0.12 966 1/18/2019
2.0.11 984 1/18/2019
2.0.10 963 1/18/2019
2.0.9 4,329 8/9/2018
2.0.8 2,306 7/17/2018
2.0.7 1,170 7/17/2018
2.0.6 2,283 6/5/2018
2.0.5 2,971 6/1/2018
2.0.4 2,437 5/22/2018
2.0.3 2,261 5/4/2018
2.0.2 2,054 2/15/2018
2.0.1 1,518 2/2/2018
2.0.0 4,339 1/2/2018
1.1.20 7,753 10/26/2017
1.1.19 2,700 10/19/2017
1.1.18 1,546 10/19/2017
1.1.17 1,166 10/19/2017
1.1.16 1,767 10/18/2017
1.1.15 1,617 10/13/2017
1.1.14 6,435 9/28/2017
1.1.13 1,182 9/28/2017
1.1.12 1,241 9/28/2017
1.1.11 1,175 9/27/2017
1.1.10 1,175 9/27/2017
1.1.9 1,216 9/27/2017
1.1.8 4,143 9/8/2017
1.1.7 1,200 9/8/2017
1.1.6 1,143 8/30/2017
1.1.5 1,151 8/29/2017
1.0.15 4,474 6/9/2017
1.0.14 1,121 6/9/2017
1.0.13 1,154 6/9/2017
1.0.12 1,168 6/9/2017
1.0.10 1,354 5/17/2017
1.0.9 1,550 3/22/2017
1.0.8 1,372 1/24/2017
1.0.7 1,164 1/24/2017
1.0.6 1,204 1/24/2017
1.0.5 1,212 12/9/2016
1.0.4 1,188 12/9/2016
1.0.3 1,554 11/21/2016