Ask Learn
Preview
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Now that .NET Core 2.1 Preview 1 has released it is time for a preview of what you can expect to see in Preview 2 and beyond in the System.IO namespace. The 2.1 release changes are the largest changes in quite some time.
Cross platform
Code should run consistently as possible between platforms. You should also be able to successfully write code that works in mixed environments. Accessing a Unix volume from Windows should just work, for example.
Light touch
System.IO's aggressive handholding blocked a number of scenarios, including mixed environments as described above. Historically this was driven partially due to Code Access Security (CAS) in NetFX (e.g. 4.x). It was also a more plausible approach when .NET was a Windows only solution to aggressively attempt to predict OS behavior. .NET judging the validity of paths is the key example of this well-intentioned, but heavy hand. We now strive to not replicate or predict the outcome of OS API calls.
Performant
This is always important to us. We want to put as little overhead on your platform and enable building performant solutions.
Flexible
We don't want to have an API for every single conceivable scenario, but neither do we want to make it impossible/difficult to build solutions. Part of addressing this is just being flexible and forward-thinking in the API set in general. Another part of this can be addressed by providing extension points that allow you to build complicated solutions in a performant way without resorting to P/Invoking directly into the underlying platform.
What are you getting from this release? Here are the highlights:
We've changed behavior to fix issues. Here are the key impacts:
In more detail this means:
The majority of what we have here are new ReadOnlySpan<char> overloads, which allow you to avoid unnecessary string allocations. Spans are a key new feature in .NET 2.1. You can pass strings as spans using the .AsSpan() extension (there is an implicit conversion as well). ReadOnlySpan<char> has a number of extensions that allow you to evaluate it as you would a string.
Join() APIs allow putting path segments together without analysis of segment rooting. Combine("C:\Foo\", "\Bar") gives you "\Bar". Join gives you "C:\Foo\Bar".
Path.GetFullPath(path, basePath) is an important addition. Normalizing paths that aren't fully qualified (e.g. relative to the current directory) is dangerous and discouraged. The reason is that the current directory is a process-wide setting. Getting into a state where a separate thread unexpectedly changes the working directory is common enough that you should make every attempt to not use the existing GetFullPath().
There have been numerous asks for directory enumeration options over the years. To fulfill some of those requests and allow addressing more we're introducing the EnumerationOptions class. The existing Directory and DirectoryInfo enumeration methods now have overloads that take this new class.
This class has some defaults that are different than historical behavior:
You can, of course, choose any setting you want.
Those options not enough? Now you can write your own fast, low level enumerators. Want your own matching algorithm? Want to total file sizes? Want to match all files with a set of extensions? Almost anything is possible with the new API that live in System.IO.Enumeration. It is a large topic, so I'll address it in the next post.
What exceptions do I get from bad paths now?
Whatever the OS tells us, we'll tell you. This will always be some sort of IOException for a bad path. Sometimes it might be a File/DirectoryNotFound. The key thing to remember is that you get exceptions when you try to use the path. GetFullPath() doesn't throw for these as it has no practical way of checking.
What if I still want to check invalid characters ?
You can do this manually using GetInvalidPathChars(). It isn't recommended as it isn't always correct on any platform. You may have NTFS/FAT volumes mounted in Unix or vice-versa.
Where did the speed improvements come from?
Primarily from reducing allocations. Keeping work on the stack and out of the heap can have a dramatic impact on large sets. Some wins come from smarter use of available OS APIs. A chunk comes from not validating paths on every single API call.
When does AttributesToSkip get applied?
First thing. One effect of this is that filtering out FileAttributes.Directory makes the RecurseSubdirectories option meaningless.
What about other file matching types?
We definitely want to add more in the future. Things like globstar (**), POSIX pattern matching notation (glob), possibly regex. With the extensibility APIs writing a custom matcher is easy. If you're passionate about any of these we're always open to contributions.
Why did you change enumeration defaults?
Note that we only changed them when you use the new EnumerationOptions class. Existing APIs should behave as they did (modulo the matching consistency fixes mentioned in the post). We picked new defaults based on OS defaults (shell & command line) and what one would expect when enumerating end-user files (e.g. to present to users). These obviously won't be right for all scenarios, but changing the settings is easy.
What about the more obscure Windows matching characters? '<', '>', and '"' were unblocked in 2.0. They're still supported, but only on Windows through the normal APIs. You can, if you want, use them on Unix if you use the extensibility points described in the next post.
Ask Learn is an AI assistant that can answer questions, clarify concepts, and define terms using trusted Microsoft documentation.
Please sign in to use Ask Learn.
Sign in