Spargine is a collection of open-source assemblies and NuGet packages designed for .NET 10, which I have been developing and maintaining since the release of .NET Framework 2. These assemblies are not only a core part of my projects but are also actively deployed in production environments across several companies I collaborate with.
Get Spargine
You can access the source code and NuGet packages here:
- GitHub: Spargine 10
- NuGet: dotNetDaveNuGet
File I/O is one of those areas where small inefficiencies quickly become big problems, especially when you’re working with large collections of files, deep directory structures, or long-running operations that need progress reporting and cancellation support. In several of my projects, I found myself repeatedly needing a fast, reliable, and safe way to handle common tasks such as copying large batches of files, deleting entire sets of files or folders, and tracking exactly what was happening during those operations.
To solve this, I created FileProcessor, part of the DotNetTips.Spargine assembly is available as a NuGet package. It centralizes and standardizes the most common file-processing workflows into a clean, high-performance API that is easy to use, resilient to errors, and designed for real-world production scenarios.
With FileProcessor, you can:
- Copy or move large collections of files with minimal boilerplate.
- Preserve original directory structures when needed.
- Safely delete files and folders in bulk.
- Track progress, performance, and errors through rich event data.
- Support cancellation for long-running operations.
In the sections below, I’ll walk you through the core methods, show how to wire up progress tracking, and demonstrate how FileProcessor can dramatically simplify your file-handling code while improving reliability and observability.
FileProcessor Methods
CopyFiles
- CopyFiles(IEnumerable<FileInfo> files, DirectoryInfo destination, bool overwrite, CancellationToken cancellationToken )
Copies files to a specified directory without throwing exceptions. - CopyFilesWithOriginalPath(IEnumerable<FileInfo> files, DirectoryInfo destination, CancellationToken cancellationToken)
Copies files to a new location using the path (excluding root) of the original file in the destination path. - MoveFiles(IEnumerable<FileInfo> files, DirectoryInfo destination,bool overwrite, CancellationToken cancellationToken)
Moves files to a new location. - MoveFilesWithOriginalPath(IEnumerable<FileInfo> files, DirectoryInfo destination, bool overwrite, CancellationToken cancellationToken)
Moves files to a new location using the path (excluding root) of the original file in the destination path.
Example Usage
First, declare FileProcessor as a field in your class:
private readonly FileProcessor _fileProcessor = new();
Next, set up an event handler in the constructor to process file copy results:
this._fileProcessor.Processed += this.Processor_Processed;
Then, call CopyFilesWithOriginalPath() and retrieve the number of successfully copied files:
foreach (var rootFiles in orderedFiles.Partition(this.PageSize))
{
filesCopied += this._fileProcessor.CopyFilesWithOriginalPath(rootFiles, userBackupLocation);
}
DeleteFiles
- DeleteFiles(IEnumerable<FileInfo> files, CancellationToken cancellationToken )
This method deletes the specified files and returns the number of successfully deleted files.
Example Usage
_ = Parallel.ForEach(files.Partition(this.PageSize), options, (page) => this._fileProcessor.DeleteFiles(page));
DeleteFolders
- DeleteFolders(IEnumerable<DirectoryInfo> folders, bool recursive, CancellationToken cancellationToken)
Deletes the specified folders and all their contents.
Example Usage
var directoriesDeleted = this._fileProcessor.DeleteFolders(folders);
Processing Results
When a file is copied, deleted, or a folder is removed, FileProgressEventArgs provides detailed information about the action. The properties of this type include:
- Message
Gets the file progress message. - Name
The full name of the file including its path. - ProgressState – Returns an enum (
FileProgressState) with the following values:- DirectoryCopied
Indicates the directory was successfully copied. - DirectoryDeleted
Indicates the directory was successfully deleted. - DirectoryMoved
Indicates the directory was successfully moved. - Error
Indicates an error occurred during the operation. - FileDeleted
Indicates the file was successfully deleted. - FileMoved
Indicates the file was successfully moved.
- DirectoryCopied
- Size
The size of the file or folder. - SpeedInMilliseconds
The time taken to complete the action (in milliseconds).
By handling the processed event, you can capture this data to log operations, display progress to users, or optimize file handling performance. Below is an example of the data in FileProgressEventArgs:
Message: "tmp5D06.tmp"
Name: "C:\\Users\\david\\AppData\\Local\\Temp\\tmp5D06.tmp"
ProgressState: FileDeleted
Size: 0
SpeedInMilliseconds: 99.8368
Summary
FileProcessor is the result of solving real problems in production code, not just theoretical API design. I actively use it in the Spargine Dev Tool, and every example shown here comes directly from that experience. It has proven itself as a dependable foundation for high-volume, high-reliability file operations.
If your applications regularly deal with:
- Large file migrations
- Backups and restores
- Cleanup utilities
- File synchronization tools
- Batch processing workflows
then FileProcessor gives you a powerful, reusable, and performance-focused solution. Instead of rewriting fragile file-handling logic in every project, you get a consistent API with built-in progress reporting, error handling, and cancellation support.
In short, FileProcessor turns file I/O from a risky, repetitive chore into a predictable, well-instrumented, and maintainable part of your application architecture.
Get Involved!
The success of open-source projects like Spargine relies on community contributions. If you find these updates useful or have ideas for further improvements, I encourage you to contribute by:
- Submitting pull requests
- Reporting issues
- Suggesting new features
Your input is invaluable in making Spargine an even more powerful tool for the .NET community.
If you are interested in contributing or have any questions, feel free to contact me via email at dotnetdave@live.com. Your support and collaboration are greatly appreciated!
Thank you, and happy coding!
Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks
Make a one-time donation
Make a monthly donation
Make a yearly donation
Choose an amount
Or enter a custom amount
Your contribution is appreciated.
Your contribution is appreciated.
Your contribution is appreciated.
DonateDonate monthlyDonate yearlyIf you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave
© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.
Discover more from dotNetTips.com
Subscribe to get the latest posts sent to your email.

