web-dev-qa-db-fra.com

Comment trouver des fichiers avec une longueur de chemin supérieure à 260 caractères dans Windows?

J'utilise une copie xcopy dans un script XP windows pour copier de manière récursive un répertoire. Je continue à avoir une erreur 'Mémoire insuffisante', ce qui, je le comprends bien, est dû au fait qu'un fichier que je tente de copier a un chemin trop long. Je peux facilement réduire la longueur du chemin, mais malheureusement, je ne peux pas déterminer quels fichiers violent la restriction de longueur de chemin. Les fichiers copiés sont imprimés sur la sortie standard (que je redirige vers un fichier journal), mais le message d'erreur est imprimé sur le terminal. Par conséquent, je ne peux même pas déterminer le répertoire dans lequel l'erreur est générée .

69
WestHamster

faire un dir /s /b > out.txt puis ajouter un guide en position 260 

Dans Powershell cmd /c dir /s /b |? {$_.length -gt 260} 

91
rerun

J'ai créé l'outil de vérification de la longueur du chemin à cette fin, qui est une application graphique agréable et gratuite que vous pouvez utiliser pour voir la longueur des chemins de tous les fichiers et répertoires d'un répertoire donné.

J'ai également écrit et écrit sur un blog à propos d'un simple script PowerShell pour obtenir la longueur des fichiers et des répertoires. Il va afficher la longueur et le chemin d'accès à un fichier, et éventuellement l'écrire également sur la console. Cela ne se limite pas à afficher des fichiers qui ne dépassent pas une certaine longueur (une modification facile à faire), mais les affiche par ordre décroissant. Il est donc toujours très facile de voir quels chemins dépassent votre seuil. C'est ici:

$pathToScan = "C:\Some Folder"  # The path to scan and the the lengths for (sub-directories will be scanned as well).
$outputFilePath = "C:\temp\PathLengths.txt" # This must be a file in a directory that exists and does not require admin rights to write to.
$writeToConsoleAsWell = $true   # Writing to the console will be much slower.

# Open a new file stream (Nice and fast) and write all the paths and their lengths to it.
$outputFileDirectory = Split-Path $outputFilePath -Parent
if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory }
$stream = New-Object System.IO.StreamWriter($outputFilePath, $false)
Get-ChildItem -Path $pathToScan -Recurse -Force | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object {
    $filePath = $_.FullName
    $length = $_.FullNameLength
    $string = "$length : $filePath"

    # Write to the Console.
    if ($writeToConsoleAsWell) { Write-Host $string }

    #Write to the file.
    $stream.WriteLine($string)
}
$stream.Close()
25
deadlydog

Pour affiner la solution la plus simple, et si vous ne pouvez ou ne voulez pas installer Powershell, exécutez simplement:

dir /s /b | sort /r /+261 > out.txt

ou (plus vite):

dir /s /b | sort /r /+261 /o out.txt

Et les lignes plus longues que 260 arriveront en haut de la liste. Notez que vous devez ajouter 1 au paramètre de colonne SORT (/ + n).

20
Chungalin

De http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/ :

Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDenied

la première partie se contente de parcourir ceci et ses sous-dossiers; using -ErrorVariable AccessDenied signifie Poussez les éléments incriminés dans la variable powershell AccessDenied.

Vous pouvez ensuite parcourir la variable comme si

$AccessDenied |
Where-Object { $_.Exception -match "must be less than 260 characters" } |
ForEach-Object { $_.TargetObject }

Si vous ne vous souciez pas de ces fichiers (peut s'appliquer dans certains cas), supprimez simplement la partie -ErrorVariable AccessDenied.

2
Jonno

J'ai proposé une alternative aux autres bonnes réponses ici qui utilise PowerShell, mais la mienne enregistre également la liste dans un fichier. Je vais le partager ici au cas où quelqu'un aurait besoin de quelque chose comme ça.

Attention: Le code remplace "longfilepath.txt" dans le répertoire de travail en cours. Je sais qu'il est peu probable que vous en ayez déjà un, mais juste au cas où!

Je le voulais volontairement en une seule ligne:

Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}

Instructions détaillées:

  1. Exécuter PowerShell
  2. Accédez au répertoire dans lequel vous souhaitez vérifier la longueur du chemin de fichier (C: fonctionne)
  3. Copiez et collez le code [cliquez sur le bouton droit de la souris pour coller dans PowerShell ou dans les touches Alt + Espace> E> P]
  4. Attendez la fin du processus, puis affichez le fichier: cat longfilepath.txt | sort

Explication:

Out-File longfilepath.txt ; - Créez (ou écrasez) un fichier vierge intitulé 'longfilepath.txt'. Point-virgule pour séparer les commandes.

cmd /c "dir /b /s /a" | - Exécutez la commande dir sur PowerShell, /a pour afficher tous les fichiers, y compris les fichiers cachés. | à pipe.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} - Pour chaque ligne (notée $ _), si la longueur est supérieure à 250, ajoutez cette ligne au fichier.

2
Rani Kheir

vous pouvez rediriger stderr.

plus d'explication ici , mais ayant une commande comme:

MyCommand >log.txt 2>errors.txt

devrait saisir les données que vous recherchez.

En outre, Windows contourne cette limitation si le chemin est préfixé par \\?\ ( msdn )

Une autre astuce si vous avez une racine ou une destination qui commence par un long chemin, peut-être que SUBST vous aidera:

SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D
2
SeanC

TLPD ("Trop long chemin répertoire") est le programme qui m'a sauvé . Très facile à utiliser:

https://sourceforge.net/projects/tlpd/

0
pollaris