Je dois écrire un outil à l'aide de .NET version 2.0 au plus haut (en utilisant quelque chose hors de l'étagère n'est pas une option pour ce client pour des raisons politiques, commerciales et de confidentialité / de confiance) de migrer des fichiers d'un serveur à un autre sur le réseau. Les serveurs sont des serveurs de fichiers pour les équipes locales et certains dossiers d'équipe doivent être migrés vers d'autres serveurs pour faciliter une réorganisation. L'idée de base est que nous lisons chaque fichier et la diffusez sur le réseau hors des heures et après quelques jours, les données seront migrées. Les autorisations de fichier doivent être préservées. Comme cela prendra quelques jours (nous parlons à plusieurs gigaoctets de données, pour certaines équipes), nous devons faire une itération sur les fichiers chaque nuit et comparer les dates de modification et les mettre à jour ceux qui ont changé. La théorie est que le nouveau serveur aura finalement une copie à jour des fichiers et les utilisateurs peuvent passer au nouveau serveur. Il n'est bien sûr pas tout à fait aussi simple, mais nous avons un design que nous pensons devoir travailler :) p>
Donc, en théorie, nous venons d'ouvrir le fichier, de la diffuser sur le réseau et de l'écrire à l'autre extrémité, non? :) p>
Malheureusement, sur les serveurs eux-mêmes, les actions de fichiers ont été créées dans des chemins de dossiers tels que: P>
D: \ Data \ Parts d'équipe \ Division \ Ministère \ Nom de l'équipe - pourrait être assez long \ p>
blockQuote>
Pour chaque utilisateur, ce chemin est mappé sur un lecteur, par exemple, il serait partagé en tant que \\ Server \ TeamName et mappé sur T: lecteur T: lecteur. P>
Ceci a provoqué la situation dans laquelle les fichiers que ceux visibles du T: lecteur sont dans la limitation Je suis conscient de la solution de contournement de spécifier des chemins à l'aide du préfixe "\\? \", qui traite le chemin comme un chemin UNC et permet un maximum théorique de 32k caractères. p>
Cette solution de contournement est mise en œuvre au niveau de l'API Win32, l'espace de noms System.IO est (principalement) essentiellement d'une fine wrapper autour des fonctions d'API Win32 natives, mais Microsoft a «utilement» mis en œuvre une validation supplémentaire (incorrecte) avant de remettre l'appel. à l'API. Dans ce cas, le .NET Framework rejette le chemin car il prétend que "?" est un caractère de chemin non valide. P>
Donc, ma question est ... Y a-t-il une façon dont je n'ai pas pensé à cela me permettra de travailler autour de cela sans avoir à réécrire complètement la quasi-totalité de l'espace de noms du système. , juste pour supprimer cette validation agaçante? P>
max_path code>, cependant, lors de la visualisation localement sur le serveur lui-même, ils vont bien au-delà de cela. Nous ne pouvons pas accéder aux fichiers à l'aide des partages réseau car cet outil doit être générique, pour exécuter des centaines de ces serveurs, et il n'y a pas de moyen standard de dire quelles actions de fichiers sont des actions que nous devrions bouger et ceux qui ne sont pas - il y a Aucun standard de convention de dénomination même. De temps en temps, il existe des sous-actions d'autres actions et nous dépassons donc le
max_path code> deux fois sur! P>
5 Réponses :
L'équipe de la BCL a fait une série de 3 parties sur la raison exactement de la raison pour laquelle ces choix ont été faits et de ce que les circonstructions de travail sont. Si vous n'avez pas encore lu cela, je vous suggère de faire comme une excellente source d'informations sur le sujet P>
Ouais j'ai vu ça. Leur solution recommandée est ce que j'essaie d'éviter d'être honnête. Comme nous traitons des métadonnées de fichiers et de répertoires, des autorisations et des contenus de fichiers, cela frappe beaucoup d'appels API, et j'espérais vraiment que quelqu'un aurait une solution réalisable qui signifierait que je n'aurais pas à passer le mois prochain pinvoke.net;)
Mes propres et autres réponses ici suggérer des bibliothèques d'emballage que vous pouvez utiliser pour traiter de longues chemins.
Il devrait être assez facile de travailler autour de cette limitation avec un peu de plate-forme invoquée, en supposant que votre logiciel dispose des autorisations nécessaires:
[DllImport("kernel32.dll", SetLastError = true)] static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); // Must close/dispose handle separately from FileStream since it's not owned by // that object when passed to constructor. using (SafeFileHandle h = CreateFile(longUncPath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)) { using (var fs = new FileStream(h, FileAccess.Read)) { // operations with FileStream object } }
Lorsque ma classe de définitions P / invoquez environ 3 000 lignes de diverses importations, structures et constantes et je n'avais toujours pas toutes les fonctionnalités dont j'avais besoin, je pensais que je viendrais ici d'abord et que je voyais si je manquais quelque chose d'évident ... ça ne semble pas :(
Je t'ai eu. Et il n'y a pas de solution tiers existante? Je suis surpris!
Vous pouvez essayer de raccourcir le chemin en mappant un répertoire parent à l'aide de SST.exe (ou quelles que soient les API utilisées en interne): P>
http : //www.makeuseof.com/tag/how-to-map-a-local-windows -folder-a-a-drive-leter/ P>
Idéalement, vous feriez ma carte autant que possible du chemin. P>
J'ai eu la réussite en supprimant les structures de répertoire en utilisant ci-dessous un petit script. Poussad utilise le format UNC qui vous donne 32k au lieu de 260 limitations