Skip to content

Add missing Invalidate() calls to FileInfo state-changing methods#124429

Open
lufen wants to merge 4 commits intodotnet:mainfrom
lufen:fix/fileinfo-invalidate-consistency
Open

Add missing Invalidate() calls to FileInfo state-changing methods#124429
lufen wants to merge 4 commits intodotnet:mainfrom
lufen:fix/fileinfo-invalidate-consistency

Conversation

@lufen
Copy link

@lufen lufen commented Feb 14, 2026

Fixes #117709 — FileInfo methods that alter file system state now call Invalidate() so cached properties (Exists, Length, timestamps) are lazily refreshed on next access, matching the pattern already used by Create(), Delete(), and MoveTo().

Methods fixed (FileInfo.cs):

  • Open(FileStreamOptions)
  • Open(FileMode, FileAccess, FileShare)
  • OpenRead()
  • OpenWrite()
  • OpenText()
  • Replace(string, string?)
  • Encrypt()
  • Decrypt()
  • CreateAsHardLink(string)

Comprehensive method audit across FileInfo, DirectoryInfo, FileSystemInfo:

FileInfo — already correct (no change needed):
Create(), Delete(), MoveTo(), CreateText(), AppendText(),
CopyTo() (returns new obj), IsReadOnly setter (via Attributes)

DirectoryInfo — already correct (no change needed):
Create(), Delete(), Delete(bool), MoveTo()
CreateSubdirectory() returns new obj, parent unchanged

FileSystemInfo — already correct (no change needed):
CreateAsSymbolicLink(), Attributes setter, CreationTime(Utc) setter,
LastAccessTime(Utc) setter, LastWriteTime(Utc) setter,
UnixFileMode setter, ResolveLinkTarget() (read-only)

Read-only methods (no invalidation needed):
GetFiles, GetDirectories, GetFileSystemInfos, Enumerate*

Includes 12 regression tests in InvalidateOnStateChange.cs covering all fixed methods plus CreateText/AppendText (already worked).

Fixes dotnet#117709 — FileInfo methods that alter file system state now call
Invalidate() so cached properties (Exists, Length, timestamps) are
lazily refreshed on next access, matching the pattern already used by
Create(), Delete(), and MoveTo().

Methods fixed (FileInfo.cs):
  - Open(FileStreamOptions)
  - Open(FileMode, FileAccess, FileShare)
  - OpenRead()
  - OpenWrite()
  - OpenText()
  - Replace(string, string?)
  - Encrypt()
  - Decrypt()
  - CreateAsHardLink(string)

Comprehensive method audit across FileInfo, DirectoryInfo, FileSystemInfo:

  FileInfo — already correct (no change needed):
    Create(), Delete(), MoveTo(), CreateText(), AppendText(),
    CopyTo() (returns new obj), IsReadOnly setter (via Attributes)

  DirectoryInfo — already correct (no change needed):
    Create(), Delete(), Delete(bool), MoveTo()
    CreateSubdirectory() returns new obj, parent unchanged

  FileSystemInfo — already correct (no change needed):
    CreateAsSymbolicLink(), Attributes setter, CreationTime(Utc) setter,
    LastAccessTime(Utc) setter, LastWriteTime(Utc) setter,
    UnixFileMode setter, ResolveLinkTarget() (read-only)

  Read-only methods (no invalidation needed):
    GetFiles, GetDirectories, GetFileSystemInfos, Enumerate*

Includes 12 regression tests in InvalidateOnStateChange.cs covering
all fixed methods plus CreateText/AppendText (already worked).

Co-authored-by: Copilot <[email protected]>
Copilot AI review requested due to automatic review settings February 14, 2026 20:22
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Feb 14, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes issue #117709 by ensuring FileInfo methods that alter or access file system state consistently call Invalidate() to refresh cached metadata. The fix addresses an inconsistency where some state-changing methods (like Create() and Delete()) called Invalidate() while others (like Open(FileMode), OpenRead(), etc.) did not, leading to stale cached properties.

Changes:

  • Added Invalidate() calls to 9 FileInfo methods that were missing them (Open variants, Replace, Encrypt/Decrypt, CreateAsHardLink)
  • Added comprehensive regression tests (12 test methods) covering all fixed methods plus verification of existing correct behavior

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs Added Invalidate() calls to Open(FileStreamOptions), Open(FileMode, FileAccess, FileShare), OpenRead(), OpenWrite(), OpenText(), Replace(), Encrypt(), Decrypt(), and CreateAsHardLink() methods
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileInfo/InvalidateOnStateChange.cs New comprehensive test file with 12 tests verifying Invalidate() behavior for all file-opening and state-changing methods
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj Added reference to new test file

…filesystems

The CreateAsHardLink_InvalidatesExists test fails with 'Too many links'
(EMLINK) on filesystems that do not support hard links. Guard the test
with MountHelper.CanCreateHardLinks, consistent with BaseHardLinks_FileSystem.

Co-authored-by: Copilot <[email protected]>
Copilot AI review requested due to automatic review settings February 15, 2026 08:10
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.IO.FileInfo .Exists and .Length inconsistencies between Open and Create

1 participant