2010-06-30 2 views
4

quelqu'un peut-il confirmer que microsoft a modifié le comportement lié à la longueur de chemin de certaines classes de System.IO dans .NET 4.0? Par exemple, le code ci-dessous s'exécute correctement sur .NET 3.5 mais sur 4.0 renvoie une exception PathTooLongException pour moi.Veuillez confirmer la modification du comportement lié à la longueur du chemin dans .NET 4.0

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()); 

En outre, un appel à File.Create(sb.ToString()) lance une IOException sur .NET 3.5, mais un PathTooLongException sur .NET 4.0. Il pourrait y avoir plus de différences.

Ces changements sont-ils documentés quelque part?

Merci!

[EDIT]

J'ai suivi les conseils de Hans et a déposé un Passant rapport sur connect.microsoft.com. Vous pouvez le trouver sur here.

+0

Pour être clair. Le nouveau comportement semble plus cohérent, car une valeur inférieure à 3.5 au-dessus du chemin ne provoquerait pas d'exception dans le constructeur de FileInfo, mais un appel ultérieur à info.Create() échouera. Je me demandais simplement s'il y a de la documentation sur ces changements. Le comportement de validation de chemin non uniforme du ctor de FileInfo et sa méthode Create sur .NET 3.5 ne sont pas soumis à cette question. – Cubicle

+0

J'ai mis à jour ma réponse avec une explication. –

Répondre

5

Modification de ma réponse, celle d'origine était incorrecte. Oui, la méthode Path.NormalizePath() a subi des modifications importantes dans .NET 4.0. J'ai réussi à obtenir ce débogué avec la source de référence et a trouvé un commentaire dans le code source qui explique son comportement:

// 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")); 
     } 

C'est l'exception qui est déclenché par votre code. Il semble visqueux parce que le code semble vérifier la longueur du nom de répertoire qui n'est évidemment pas proche de 255 caractères dans votre code. Toutefois, le commentaire explique pourquoi votre chemin est rejeté, la partie du nom de fichier du chemin est 259-3 = 256 caractères. Un de trop.

Je n'étais pas au courant de cette restriction et je suis un peu douteux que toutes les versions de Windows ont cette restriction. Tout ce que j'ai vu documenté qu'il y a en effet une longueur maximale du nom du répertoire (chemin moins nom de fichier). Il y a d'autres commentaires dans le code qui suggèrent qu'il existe un bogue off-by-one dans Windows 2000, qui pourrait avoir quelque chose à voir avec ça.

Anyhoo, vous pouvez voir par vous-même en changeant

 const string prefix = "C:\\a\\"; 

Et maintenant, une chaîne de chemin de 259 caractères est accepté. En d'autres termes, ce comportement ne doit être octet que si le nom du chemin fait référence au dossier racine du lecteur. Pas un endroit où vous devriez stocker des fichiers. Étant donné le commentaire dans le code source, ce changement était tout à fait intentionnel et devrait être considéré comme une fonctionnalité, pas un bogue. Néanmoins, j'ai posté un commentaire sur l'article que vous avez commencé à rédiger. Je ne l'achète toujours pas complètement ...


Mise à jour: d'accord, je suis vendu dessus. J'ai essayé de créer un tel fichier en utilisant C++ sur Win7 et il a échoué. Les fichiers du répertoire racine ne peuvent en effet pas comporter de noms de chemin plus longs que 258 caractères. La restriction semble être induite par un composant du chemin (nom de sous-répertoire, nom de fichier) ne doit pas être plus long que 255 caractères. Le comportement .NET 4.0 est entièrement correct.

+0

Il me semble que le PO a demandé une citation à la documentation, ayant déjà déterminé les faits tels que vous les représentez. –

+0

Heath Hunnicutt a raison. Je sais que MAX_PATH inclut le zéro final. Thats ce que le - 1 est pour. La longueur totale de mon chemin d'exemple devrait être 260 y compris le zéro. – Cubicle

+1

@Cubicle: tu as raison, ça sent comme un bug. Je ne le vois pas en regardant le code, il a été complètement réécrit pour .NET 4.0 et est assez compliqué. J'ai essayé de répondre à votre demande de documentation, pensez à utiliser connect.microsoft.com pour déposer un rapport et demander des éclaircissements. Je ne vois pas de rapport similaire. –

0

Avez-vous examiné les méthodes File.Create() dans le réflecteur, et avez-vous comparé les deux versions?

+0

J'ai creusé en quelques pas, mais j'ai abandonné après un moment. Malheureusement je ne peux pas y passer beaucoup de temps. Ce n'est pas un gros problème après tout. – Cubicle

Questions connexes