WriteableFileProviders.Physical
2027.0.0
See the version list below for details.
dotnet add package WriteableFileProviders.Physical --version 2027.0.0
NuGet\Install-Package WriteableFileProviders.Physical -Version 2027.0.0
<PackageReference Include="WriteableFileProviders.Physical" Version="2027.0.0" />
<PackageVersion Include="WriteableFileProviders.Physical" Version="2027.0.0" />
<PackageReference Include="WriteableFileProviders.Physical" />
paket add WriteableFileProviders.Physical --version 2027.0.0
#r "nuget: WriteableFileProviders.Physical, 2027.0.0"
#:package WriteableFileProviders.Physical@2027.0.0
#addin nuget:?package=WriteableFileProviders.Physical&version=2027.0.0
#tool nuget:?package=WriteableFileProviders.Physical&version=2027.0.0
WriteableFileProviders.Physical
A folder on the local disk as an IWriteableFileProvider, with atomic writes and change notifications. Part of
WriteableFileProviders.
Install
dotnet add package WriteableFileProviders.Physical
Needs .NET 10, and is native AOT compatible. Keep every WriteableFileProviders package in an app on the same major version.
Use
using WriteableFileProviders;
using WriteableFileProviders.Physical;
await using var files = new WriteablePhysicalFileProvider("/srv/files");
await files.UpdateFileAsync("reports/2026.csv", stream); // creates reports/ if missing
await files.UpdateFileAsync("app.log", line, UpdateFileOptions.Append);
await using var slice = await files.ReadRangeAsync("big.bin", 1_000_000, 4096);
var changed = files.Watch("reports/*.csv");
From configuration, with WriteableFileProviderSerializer.FromConfiguration(section) or
services.AddWriteableFileProvider(section):
{ "Files": { "Type": "WriteablePhysicalFileProvider", "RootDirectoryPath": "/srv/files" } }
Configuration
| Option | Default | Meaning |
|---|---|---|
RootDirectoryPath |
required | The folder the provider is confined to: absolute (/srv/files, C:\files, \\server\share\files) or relative to the current directory, resolved once when the provider is built. It need not exist; the first write creates it. |
RootDirectorySegments |
The same folder as segments, the form 2026 stored: ["root:", "srv", "files"], ["C:", "files"], ["\\", "server", "share"]. Set this or RootDirectoryPath. |
Authentication
None. The provider reads and writes with the permissions of the process.
What's different
- Writes are atomic. An overwrite, an append, a copy or a local stream's commit writes
.wfp-<guid>.tmpnext to the target, then renames it over the target. Listings hide these files; a crash can leave one, which you can delete. - An append copies the whole file, so frequent appends to a large file (a log) are expensive.
- A write puts a new file at the path. Other hard links keep the old content, and a symbolic link at the path becomes a file. On Windows the file takes the folder's permissions; on Linux and macOS, the old file's mode bits. ACLs and extended attributes are not kept.
IfMatchis not atomic. It is checked just before the rename. ETags come from the last-write time and length.- On Windows, a write to a file that is open for reading fails (
UnauthorizedAccessExceptionorIOException), and the file keeps its content. Linux and macOS let the write go ahead. - Case is ignored on Windows and macOS, and matters elsewhere.
:is refused in names everywhere. On Windows, so are names Windows can't hold or would read as another name:report.txt.,a?b,CON,con.txt. Listings leave out such names, and on Linux and macOS, names holding:or\. - Symbolic links and junctions inside the root are followed, wherever they point. A recursive listing lists a linked folder but doesn't walk into it.
- No content types.
UpdateFileOptions.ContentTypeis ignored;ContentTypeis null. Watchworks like ASP.NET Core'sPhysicalFileProvider: a glob relative to the root. Hidden and dot-prefixed files aren't watched. Where file system events don't arrive (some network and container mounts), setDOTNET_USE_POLLING_FILE_WATCHER=1.- No native signed URLs.
GetSignedUrlAsyncthrowsNotSupportedException. For download and upload links, use the gateway in WriteableFileProviders.AspNetCore.
Learn more
- Getting started: local files first, then download links through the gateway.
- The guide: reading and writing, paths and listings, errors, providers compared.
- Moving from 2026.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.FileProviders.Physical (>= 10.0.12)
- WriteableFileProviders.Common (>= 2027.0.0 && < 2028.0.0-alpha)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2027.1.1 | 43 | 10/13/2026 |
| 2027.1.1-rc.1 | 42 | 10/13/2026 |
| 2027.1.0 | 73 | 10/12/2026 |
| 2027.1.0-rc.1 | 49 | 10/12/2026 |
| 2027.0.0 | 360 | 10/11/2026 |
| 2027.0.0-rc.2 | 63 | 10/11/2026 |
What each release changed: https://github.com/serionist/WriteableFileProviders/blob/main/CHANGELOG.md. Moving from 2026.x: https://github.com/serionist/WriteableFileProviders/blob/main/docs/migration-2027.md