Skip to content

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

@daxian-dbw

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

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions