Please confirm change in path length related behaviour in .NET 4.0
can someone confirm that microsoft changed path length related behaviour of some classe from System.IO in .NET 4.0? For example the code below runs fine on .NET 3.5 but on 4.0 throws a PathTooLongException for me.
const string prefix = "C:\\";
const string suffix = ".txt";
var sb = new StringBuilder();
sb.Append(prefix);
for (var i = 0; i < 260 - prefix.Length - suffix.Length - 1; i++)
{
sb.Append("a");
}
开发者_高级运维sb.Append(suffix);
var info = new FileInfo(sb.ToString());
Also, a call to File.Create(sb.ToString())
throws an IOException on .NET 3.5 but an PathTooLongException on .NET 4.0. There might more differences.
Are these changes documented somewhere?
Thank You!
[EDIT]
I followed Hans Passant's advice and filed a report on connect.microsoft.com. You can find it over here.
Editing my answer, the original one was incorrect. Yes, the Path.NormalizePath() method went through some major changes in .NET 4.0. I managed to get this debugged with the Reference Source and found a comment in the source code that explains its behavior:
// The max total path is 260, and the max individual component length is 255.
// For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
internal static readonly int MaxPath = 260;
private static readonly int MaxDirectoryLength = 255;
...
if (newBuffer.Length - 1 - lastDirectorySeparatorPos > MaxDirectoryLength)
{
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
}
That's the exception that is tripped by your code. It looks screwy because the code appears to check the directory name length which is obviously not close to 255 chars in your code. However, the comment explains why your path is rejected, the file name part of the path is 259-3 = 256 characters. One too many.
I was not previously aware of this restriction and am a bit doubtful that all versions of Windows have this restriction. All I've seen documented that there's indeed a maximum length of the directory name (path minus filename). There are other comments in the code that suggest that there is an off-by-one bug in Windows 2000, that might have something to do with it.
Anyhoo, you can see this for yourself by changing
const string prefix = "C:\\a\\";
And now a path string of 259 chars is accepted. In other words, this behavior should only ever byte if the path name refers to the drive root folder. Not a place where you ever should store files.
Given the comment in the source code, this change was quite intentional and should be regarded as a feature, not a bug. Nevertheless, I posted a comment to the feedback article you started. I'm still not buying it completely...
Update: okay I'm sold on it. I tried creating such a file using C++ on Win7 and it failed. Files in the root directory indeed cannot have path names longer than 258 chars. The restriction appears to be induced by a component of the path (subdirectory name, file name) not allowed to be longer than 255 chars. The .NET 4.0 behavior is entirely correct.
Have you examined the File.Create()
methods in reflector, and compared the two versions?
精彩评论