-
Notifications
You must be signed in to change notification settings - Fork 5.4k
FileSystemInfo.Attributes set to -1 if the file gets deleted while in an enumeration on Unix #22033
Description
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:
- Inconsistent behavior between Windows and Unix platforms.
- On Windows,
filesystemInfo.Attributesreturns the original attributes even though the file gets deleted during the enumeration.
- On Windows,
- Breaking change in behavior from
Microsoft.NetCore.App 2.0.0-preview1-002106-00toMicrosoft.NetCore.App 2.0.0-preview2-25324-03- With version
2.0.0-preview1-002106-00,filesystemInfo.Attributesraises anFileNotFoundExceptionexception. - With version
2.0.0-preview2-25324-03,filesystemInfo.Attributesreturns -1
- With version
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