FileCurator 4.0.71

dotnet add package FileCurator --version 4.0.71
NuGet\Install-Package FileCurator -Version 4.0.71
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="4.0.71" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FileCurator --version 4.0.71
#r "nuget: FileCurator, 4.0.71"
#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=4.0.71

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

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 an IoC wrapper called Canister. While Canister has a built in IoC container, it's purpose is to actually wrap your container of choice in a way that simplifies setup and usage for other libraries that don't want to be tied to a specific IoC container. FileCurator uses it to detect and pull in file system providers. As such you must set up Canister in order to use FileCurator:

services.AddCanisterModules(configure => configure.RegisterFileCurator());

This line is required prior to using the extension methods, FileInfo, and DirectoryInfo classes for the first time. Once Canister 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
  • And of course TXT files...

There are also a few items that are not .Net Core/.Net Standard supported in the FileCurator.Windows package:

  • PDF
  • MSG files
  • RTF

Once a .Net Standard library is available to parse these items that is open sourced (and without a funky license), these will be moved into the main library. Anyway, 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

The file parsers that are not .Net Standard yet are also available with the package name of "FileCurator.Windows". To install it run the following command in the Package Manager Console:

Install-Package FileCurator.Windows

This package, however, is .Net Framework only and generally not needed as most formats have been moved to .Net Standard/.Net 5+.

Build Process

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

  1. Visual Studio 2019
  2. .Net 5

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 net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
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.

Enlighten

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

TestFountain

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

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
4.0.71 223 3/15/2024
4.0.70 210 3/14/2024
4.0.69 270 3/13/2024
4.0.68 606 3/8/2024
4.0.67 200 3/7/2024
4.0.66 119 3/6/2024
4.0.65 154 3/5/2024
4.0.64 166 3/4/2024
4.0.63 377 2/28/2024
4.0.62 1,275 2/27/2024
4.0.61 414 2/23/2024
4.0.60 138 2/22/2024
4.0.59 173 2/21/2024
4.0.58 403 2/20/2024
4.0.57 417 2/15/2024
4.0.56 164 2/14/2024
4.0.55 238 2/9/2024
4.0.54 268 2/7/2024
4.0.53 163 2/6/2024
4.0.52 2,160 2/5/2024
4.0.51 951 1/31/2024
4.0.50 242 1/30/2024
4.0.49 300 1/29/2024
4.0.48 472 1/23/2024
4.0.47 602 1/22/2024
4.0.46 523 1/11/2024
4.0.45 647 1/10/2024
4.0.44 1,258 12/25/2023
4.0.43 621 12/21/2023
4.0.42 587 12/14/2023
4.0.41 267 12/13/2023
4.0.40 289 12/12/2023
4.0.39 2,007 11/23/2023
4.0.38 525 11/20/2023
4.0.37 392 11/17/2023
4.0.36 204 11/16/2023
4.0.35 642 11/13/2023
4.0.34 605 11/7/2023
4.0.33 312 11/6/2023
4.0.32 830 10/31/2023
4.0.31 332 10/30/2023
4.0.30 678 10/25/2023
4.0.29 811 10/11/2023
4.0.28 489 10/4/2023
4.0.27 429 9/25/2023
4.0.26 605 9/19/2023
4.0.25 220 9/18/2023
4.0.24 766 9/13/2023
4.0.23 362 9/12/2023
4.0.22 416 9/11/2023
4.0.21 819 9/6/2023
4.0.20 364 9/5/2023
4.0.19 363 9/4/2023
4.0.18 473 9/1/2023
4.0.17 363 8/31/2023
4.0.16 389 8/30/2023
4.0.15 442 8/29/2023
4.0.14 430 8/28/2023
4.0.13 568 8/24/2023
4.0.12 550 8/22/2023
4.0.11 604 8/17/2023
4.0.10 1,408 8/9/2023
4.0.9 500 8/8/2023
4.0.8 378 8/7/2023
4.0.7 820 8/2/2023
4.0.6 546 7/25/2023
4.0.5 437 7/19/2023
4.0.4 514 7/14/2023
4.0.3 162 7/13/2023
4.0.2 136 7/11/2023
4.0.1 393 12/13/2022
4.0.0 2,100 12/12/2022
3.1.46 1,556 8/15/2022
3.1.45 774 7/6/2022
3.1.44 2,830 6/6/2022
3.1.42 578 5/26/2022
3.1.41 1,136 1/20/2022
3.1.40 4,530 1/11/2022
3.1.39 673 1/10/2022
3.1.37 925 8/25/2021
3.1.36 1,390 7/19/2021
3.1.35 464 7/12/2021
3.1.34 839 6/15/2021
3.1.33 476 5/21/2021
3.1.31 444 5/20/2021
3.1.30 407 5/20/2021
3.1.29 2,323 4/30/2021
3.1.28 3,901 3/12/2021
3.1.27 507 3/11/2021
3.1.26 424 2/20/2021
3.1.25 1,835 1/6/2021
3.1.24 504 1/6/2021
3.1.23 514 12/15/2020
3.1.21 534 12/2/2020
3.1.20 566 9/17/2020
3.1.19 574 9/16/2020
3.1.18 526 9/16/2020
3.1.17 1,971 9/13/2020
3.1.16 1,305 7/29/2020
3.1.15 555 7/29/2020
3.1.14 586 7/16/2020
3.1.13 875 6/7/2020
3.1.12 663 6/7/2020
3.1.11 607 5/5/2020
3.1.10 624 4/30/2020
3.1.9 623 4/30/2020
3.1.8 1,652 4/28/2020
3.1.7 543 4/28/2020
3.1.6 1,177 4/10/2020
3.1.5 2,597 3/25/2020
3.1.4 815 3/25/2020
3.1.3 1,483 3/19/2020
3.1.2 2,148 3/1/2020
3.0.1 682 3/1/2020
3.0.0 4,866 12/23/2019
2.0.17 881 9/26/2019
2.0.16 1,192 4/17/2019
2.0.15 1,119 4/16/2019
2.0.14 3,887 2/21/2019
2.0.13 949 1/18/2019
2.0.12 921 1/18/2019
2.0.11 943 1/18/2019
2.0.10 924 1/18/2019
2.0.9 4,109 8/9/2018
2.0.8 2,221 7/17/2018
2.0.7 1,123 7/17/2018
2.0.6 2,203 6/5/2018
2.0.5 2,828 6/1/2018
2.0.4 2,353 5/22/2018
2.0.3 2,197 5/4/2018
2.0.2 1,984 2/15/2018
2.0.1 1,462 2/2/2018
2.0.0 4,172 1/2/2018
1.1.20 7,485 10/26/2017
1.1.19 2,612 10/19/2017
1.1.18 1,479 10/19/2017
1.1.17 1,112 10/19/2017
1.1.16 1,700 10/18/2017
1.1.15 1,553 10/13/2017
1.1.14 6,221 9/28/2017
1.1.13 1,129 9/28/2017
1.1.12 1,197 9/28/2017
1.1.11 1,131 9/27/2017
1.1.10 1,133 9/27/2017
1.1.9 1,154 9/27/2017
1.1.8 4,010 9/8/2017
1.1.7 1,163 9/8/2017
1.1.6 1,093 8/30/2017
1.1.5 1,106 8/29/2017
1.0.15 4,298 6/9/2017
1.0.14 1,078 6/9/2017
1.0.13 1,108 6/9/2017
1.0.12 1,130 6/9/2017
1.0.10 1,304 5/17/2017
1.0.9 1,479 3/22/2017
1.0.8 1,323 1/24/2017
1.0.7 1,119 1/24/2017
1.0.6 1,161 1/24/2017
1.0.5 1,156 12/9/2016
1.0.4 1,145 12/9/2016
1.0.3 1,492 11/21/2016