Table of Contents

Class FileTypeRegistry

Namespace
HeroKit.FileTypes
Assembly
HeroKit.FileTypes.dll

A set of file types with detection by content and lookup by extension and MIME type.

public sealed class FileTypeRegistry
Inheritance
FileTypeRegistry
Inherited Members
Extension Methods

Examples

var registry = new FileTypeRegistry(); // the built-in types
registry.Register(new FileType("Sketch document", "application/x-sketch", FileTypeCategory.Document, "sketch")
{
    Detectors = [new ZipEntryDetector("document.json")],
    Parent = FileTypes.Zip,
});
services.AddSingleton(registry);

Remarks

Default holds the built-in types and is what the static FileTypes methods use. Create your own instance to keep custom types out of the shared registry, for example per tenant, in tests or through dependency injection.

The registry is thread-safe. Register(FileType) replaces an internal snapshot, so readers never see a half-updated state.

Detection reads magic bytes from the start of a file. It is a first check, not a proof: a file can be crafted to match a type.

Constructors

FileTypeRegistry()

Creates a registry with the built-in types (BuiltIn).

public FileTypeRegistry()

FileTypeRegistry(IEnumerable<FileType>)

Creates a registry with only the given types, in detection order: put specific types before the types they are built on.

public FileTypeRegistry(IEnumerable<FileType> types)

Parameters

types IEnumerable<FileType>

The types.

Fields

DefaultMimeType

The MIME type for unknown binary content: "application/octet-stream".

public const string DefaultMimeType = "application/octet-stream"

Field Value

string

HeaderSize

The number of bytes read from the start of a stream for detection: 16 KB.

public const int HeaderSize = 16384

Field Value

int

Properties

All

Gets all types: registered types first (newest first), then the types given to the constructor.

public IReadOnlyList<FileType> All { get; }

Property Value

IReadOnlyList<FileType>

Methods

ContentMatchesExtension(Stream, string?)

Checks whether the start of a stream fits the extension of a file name. Reads at most HeaderSize bytes and restores the position of a seekable stream.

public bool ContentMatchesExtension(Stream stream, string? fileName)

Parameters

stream Stream

The stream, positioned at the start of the file.

fileName string

The file name or extension.

Returns

bool

True if both are known and fit.

ContentMatchesExtension(ReadOnlySpan<byte>, string?)

Checks whether the content of a file fits the extension of its name.

public bool ContentMatchesExtension(ReadOnlySpan<byte> header, string? fileName)

Parameters

header ReadOnlySpan<byte>

The first bytes of the file.

fileName string

The file name or extension.

Returns

bool

True if both are known and fit; false if either is unknown or they differ.

Remarks

The content fits when the detected type is the extension's type, or one is built on the other through Parent: a ".docx" whose entries are beyond the header is accepted as ZIP, and a ".csv" is accepted as plain text.

Detect(Stream)

Detects the type of a file from the start of a stream. Reads HeaderSize bytes and, for a seekable ZIP file, its central directory (at most 1 MB), so DOCX, XLSX and similar files are recognized even when their entries are far from the start. Restores the position of a seekable stream.

public FileType? Detect(Stream stream)

Parameters

stream Stream

The stream, positioned at the start of the file.

Returns

FileType

The first matching type, or null.

Detect(ReadOnlySpan<byte>)

Detects the type of a file from its first bytes.

public FileType? Detect(ReadOnlySpan<byte> header)

Parameters

header ReadOnlySpan<byte>

The first bytes of the file. HeaderSize bytes are enough for every built-in type; a longer span lets the ZIP detectors see more entries.

Returns

FileType

The first matching type, or null if no type matches.

DetectAll(ReadOnlySpan<byte>)

Returns every type whose detectors match the first bytes of a file, for example both DOCX and ZIP.

public IReadOnlyList<FileType> DetectAll(ReadOnlySpan<byte> header)

Parameters

header ReadOnlySpan<byte>

The first bytes of the file.

Returns

IReadOnlyList<FileType>

The matching types in detection order; empty if none match.

DetectAsync(Stream, CancellationToken)

Detects the type of a file from the start of a stream asynchronously. Reads like Detect(Stream) and restores the position of a seekable stream.

public ValueTask<FileType?> DetectAsync(Stream stream, CancellationToken cancellationToken = default)

Parameters

stream Stream

The stream, positioned at the start of the file.

cancellationToken CancellationToken

A token to cancel the read.

Returns

ValueTask<FileType>

The first matching type, or null.

FromExtension(string?)

Finds a type by the extension of a file name or by an extension, ignoring case.

public FileType? FromExtension(string? fileNameOrExtension)

Parameters

fileNameOrExtension string

A file name or path ("photo.JPG"), an extension with a dot (".jpg") or without one ("jpg").

Returns

FileType

The type, or null if the extension is unknown or missing.

FromMimeType(string?)

Finds a type by its MIME type, ignoring case and parameters such as "; charset=utf-8".

public FileType? FromMimeType(string? mimeType)

Parameters

mimeType string

The MIME type, for example "image/jpeg" or "image/x-icon".

Returns

FileType

The type, or null if the MIME type is unknown.

GetMimeType(string?)

Returns the MIME type for a file name, for example for a Content-Type header.

public string GetMimeType(string? fileNameOrExtension)

Parameters

fileNameOrExtension string

A file name, path or extension.

Returns

string

The MIME type, or DefaultMimeType if the extension is unknown.

Register(FileType)

Registers a file type. It is checked before the other types, and its extensions and MIME types win.

public void Register(FileType fileType)

Parameters

fileType FileType

The type.