Pascal Demets pascal
  • Mouscron, Belgium
  • Joined on 2024-08-09

QDM.SafeFileManager (1.0.0)

Published 2026-05-10 18:57:29 +02:00 by pascal

Installation

dotnet nuget add source --name pascal --username your_username --password your_token https://gitea.2mets.be/api/packages/pascal/nuget/index.json
dotnet add package --source pascal --version 1.0.0 QDM.SafeFileManager

About this package

Save file management

FileManager — Reliable File I/O Utilities for .NET

The FileManager library provides a set of robust, concurrency‑friendly, and high‑performance file‑handling utilities for .NET applications. It includes synchronous and asynchronous methods for reading, writing, appending, and performing atomic file operations, along with retry helpers for transient I/O failures.

These utilities are designed for scenarios where correctness, safety, and performance matter—such as logging, configuration management, and shared file access.


Features

  • Streaming reads (IEnumerable / IAsyncEnumerable)
  • Full‑file reads (sync + async)
  • Atomic writes using File.Replace
  • Append operations with concurrent access
  • Retry helpers for transient IOException
  • UTF‑8 encoding with BOM‑less support
  • Concurrency‑safe via FileShare.ReadWrite
  • Optimized file access using SequentialScan and async I/O

Reading Methods

ReadLines

Reads a file lazily, line by line, without loading the entire file into memory.
See: Explain ReadLines

Behavior

  • Returns IEnumerable<string>
  • Skips execution if the file does not exist
  • Uses FileShare.ReadWrite to allow concurrent access
  • Efficient for large files and log processing

ReadLinesAsync

Asynchronous streaming line reader.
See: Explain ReadLinesAsync

Behavior

  • Returns IAsyncEnumerable<string>
  • Uses ReadLineAsync() until EOF
  • Avoids blocking calls inside async loops
  • Ideal for scalable server workloads

Read

Reads the entire file into a single string.
See: Explain Read

Behavior

  • Returns string.Empty if the file does not exist
  • Uses UTF‑8 encoding
  • Suitable for small and medium files

ReadAsync

Asynchronous full‑file read.
See: Explain ReadAsync

Behavior

  • Uses ReadToEndAsync()
  • Non‑blocking
  • Recommended for UI apps and async pipelines

Writing Methods

WriteAtomic

Writes content to a file atomically, ensuring no partial writes occur.
See: Explain WriteAtomic

How It Works

  1. Writes content to a temporary file in the same directory
  2. Uses File.Replace to atomically swap the temp file with the target
  3. Cleans up the temp file on failure

Guarantees

  • Crash‑safe
  • No torn writes
  • Consistent file state

WriteAtomicAsync

Asynchronous atomic write.
See: Explain WriteAtomicAsync

Behavior

  • Uses WriteAllTextAsync
  • Performs the same atomic replacement as the sync version
  • Ideal for high‑throughput async workflows

Append Methods

AppendLine

Appends a single line to the file.
See: Explain AppendLine

Behavior

  • Opens file in append mode
  • Writes UTF‑8 text
  • Allows concurrent readers/writers
  • Not atomic (multiple writers may interleave)

Best For

Logging, audit trails, incremental output.


AppendLineAsync

Asynchronous append operation.
See: Explain AppendLineAsync

Behavior

  • Uses WriteAsync
  • Non‑blocking
  • Suitable for high‑volume logging systems

Retry Helpers

WithRetries

Synchronous retry wrapper for transient I/O failures.
See: Explain WithRetries

Behavior

  • Accepts an Action
  • Retries on IOException
  • Sleeps between attempts using Thread.Sleep
  • Default: 3 retries, 200ms delay

WithRetriesAsync

Asynchronous retry wrapper.
See: Explain WithRetriesAsync

Behavior

  • Accepts a Func<Task>
  • Retries on IOException
  • Uses Task.Delay between attempts
  • Non‑blocking and scalable

Design Principles

Concurrency Safety

See: Explain FileShare.ReadWrite

All methods use FileShare.ReadWrite to allow:

  • Multiple readers
  • Readers + writers
  • Writers that append

This prevents unnecessary locking and supports log‑style workflows.


Streaming vs. Full Reads

See: Compare Streaming vs Full Reads

Choose based on file size:

  • Streaming (ReadLines, ReadLinesAsync)

    • Best for large files
    • Minimal memory usage
  • Full reads (Read, ReadAsync)

    • Best for small/medium files
    • Simpler usage

Atomicity Guarantees

See: Explain Atomic File Writes

Atomic writes ensure:

  • No partial files
  • Crash‑safe updates
  • Consistent state

Implemented via File.Replace, which is atomic on NTFS.

Dependencies

ID Version Target Framework
Microsoft.Bcl.AsyncInterfaces 10.0.7 .NETStandard2.1
Details
NuGet
2026-05-10 18:57:29 +02:00
1
Pascal Demets
14 KiB
Assets (2)
Versions (1) View all
1.0.0 2026-05-10