Skip to content

FileSystemInfo.Attributes set to -1 if the file gets deleted while in an enumeration on Unix #22033

Closed

Description

@daxian-dbw

Summary

When a file gets deleted (or renamed) during an enumeration of all files in the parent directory, accessing the 'Attributes' property of the FileInfo object returns value '-1'. This seems very bad to me because it's not a meaningful FileAttributes value and thus the subsequent tests like (filesystemInfo.Attributes & FileAttributes.Hidden) != 0 will give unexpected results and cause problems.

There are 2 issues in my observation:

  1. Inconsistent behavior between Windows and Unix platforms.
    • On Windows, filesystemInfo.Attributes returns the original attributes even though the file gets deleted during the enumeration.
  2. Breaking change in behavior from Microsoft.NetCore.App 2.0.0-preview1-002106-00 to Microsoft.NetCore.App 2.0.0-preview2-25324-03
    • With version 2.0.0-preview1-002106-00, filesystemInfo.Attributes raises an FileNotFoundException exception.
    • With version 2.0.0-preview2-25324-03, filesystemInfo.Attributes returns -1

Thought

I think it would be the best if we can have the consistent behavior between Windows and Unix platforms.
If that's technically not possible, then throwing FileNotFoundException exception is better than returnning -1 because -1 is not a meaningful value for FileAttributes and it will mislead the subsequent code.

Repro

Program.cs

using System;
using System.IO;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            string testDir = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "temp");
            DirectoryInfo dir = new DirectoryInfo(testDir);
            foreach (FileSystemInfo fileSystemInfo in dir.EnumerateFiles())
            {
                if (string.Equals(fileSystemInfo.Name, "bb.txt", StringComparison.InvariantCulture))
                {
                    File.Delete(fileSystemInfo.FullName);
                }

                try {
                    Console.WriteLine("{0} - {1}", fileSystemInfo.Name, fileSystemInfo.Attributes);
                } catch (System.IO.FileNotFoundException ex) {
                    Console.WriteLine("{0}: {1}", ex.GetType().FullName, ex.Message);
                    Console.WriteLine(ex.StackTrace);
                }
            }
        }
    }
}

Result:

## Linux
## .NET Command Line Tools (2.0.0-preview1-005952)
## Microsoft .NET Core Shared Framework Host
##   Version  : 2.0.0-preview1-002106-00
##   Build    : 86fe9816c8ba782241c441c3228c665e393c3ef3
> dotnet run
cc.txt - Normal
System.IO.FileNotFoundException: Could not find file '/home/pi/temp/bb.txt'.
   at System.IO.FileSystemInfo.EnsureStatInitialized()
   at System.IO.FileSystemInfo.System.IO.IFileSystemObject.get_Attributes()
   at System.IO.FileSystemInfo.get_Attributes()
   at test.Program.Main(String[] args)
aa.txt - Normal
## Linux
## .NET Command Line Tools (2.0.0-preview2-006195)
## Microsoft .NET Core Shared Framework Host
##    Version  : 2.0.0-preview2-25324-03
##    Build    : b6c9f8ad69dc3edd601e288198de27975b514306
> dotnet run
bb.txt - -1
aa.txt - Normal
cc.txt - Normal
## Windows
## .NET Command Line Tools (2.0.0-preview2-006195)
## Microsoft .NET Core Shared Framework Host
##    Version  : 2.0.0-preview2-25324-03
##    Build    : b6c9f8ad69dc3edd601e288198de27975b514306
> dotnet run
aa.txt - Archive
bb.txt - Archive
cc.txt - Archive

Activity

  1. danmoseley commented on May 30, 2017

    @danmoseley
    Contributor

    @JeremyKuhne please evaluate whether this needs to be in 2.0

  2. JeremyKuhne commented on May 31, 2017

    @JeremyKuhne
    Member

    The issue here is more around state refresh rather than "bad" behavior. If the file is missing in desktop (.NET FX) you get -1 if the state gets/needs refreshed. Desktop never throws on Attributes access. We should look at getting the "refresh" state in better alignment, but going back to throwing isn't a portable answer.

    Fyi, I'm in the process of updating the documentation about this behavior.

  3. JeremyKuhne commented on May 31, 2017

    @JeremyKuhne
    Member

    Putting in 2.0 so we can look at what it takes to get the refresh state aligned.

  4. danmoseley commented on Jun 14, 2017

    @danmoseley
    Contributor

    @JeremyKuhne I guess we can close this

  5. daxian-dbw commented on Jun 14, 2017

    @daxian-dbw
    ContributorAuthor

    Thanks for the fix! Where can I find the documentation about this behavior on both Windows and Unix?

  6. JeremyKuhne commented on Jun 14, 2017

    @JeremyKuhne
    Member

    Thanks for the fix! Where can I find the documentation about this behavior on both Windows and Unix?

    I've got a change in process to update the docs to describe the current behavior. dotnet/docs#2209 I've been busy getting the fixes through, I should hopefully get it finished shortly.

  7. transferred this issue fromdotnet/corefxon Jan 31, 2020
  8. added this to the 2.0.0 milestone on Jan 31, 2020
  9. ghost locked as resolved and limited conversation to collaborators on Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions