it-swarm.com.ru

Как найти файлы с длиной пути более 260 символов в Windows?

Я использую xcopy в XP сценарии Windows для рекурсивного копирования каталога. Я получаю сообщение об ошибке «Недостаточно памяти», которое, как я понимаю, связано с тем, что у файла, который я пытаюсь скопировать, слишком длинный путь. Я могу легко уменьшить длину пути, но, к сожалению, я не могу понять, какие файлы нарушают ограничение длины пути. Скопированные файлы печатаются на стандартный вывод (который я перенаправляю в файл журнала), но сообщение об ошибке выводится на терминал, поэтому я даже не могу точно определить, для какого каталога выдается ошибка ,.

69
WestHamster

сделать dir /s /b > out.txt и затем добавить руководство в позиции 260 

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

91
rerun

Для этого я создал инструмент проверки длины пути , который представляет собой хорошее бесплатное приложение с графическим интерфейсом, которое вы можете использовать для просмотра длины пути всех файлов и каталогов в данном каталоге.

Я также написал и написал в блоге о простом скрипте PowerShell для получения длины файлов и каталогов. Он выведет длину и путь к файлу, а также опционально запишет его в консоль. Он не ограничивается отображением файлов, длина которых превышает определенную длину (это легко сделать), но отображает их по убыванию по длине, так что все еще очень легко увидеть, какие пути превышают ваш порог. Вот:

$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

В качестве усовершенствования простейшего решения, и если вы не можете или не хотите устанавливать Powershell, просто запустите:

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

или (быстрее):

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

И строки длиннее 260 попадут в начало списка. Обратите внимание, что вы должны добавить 1 к параметру столбца SORT (/ + n).

20
Chungalin

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

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

первая часть просто перебирает эту и вложенные папки; использование -ErrorVariable AccessDenied означает, что вы отправите нарушающие элементы в переменную powershell AccessDenied.

Затем вы можете просмотреть переменную следующим образом

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

Если вас не интересуют эти файлы (в некоторых случаях это применимо), просто удалите часть -ErrorVariable AccessDenied.

2
Jonno

Я сделал альтернативу другим хорошим ответам, которые используют PowerShell, но мой также сохраняет список в файл. Поделюсь здесь, если кому-то еще понадобится что-то подобное.

Предупреждение: Код перезаписывает "longfilepath.txt" в текущем рабочем каталоге. Я знаю, что вряд ли он у вас уже есть, но на всякий случай!

Умышленно хотел это в одну строчку:

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

Подробные инструкции:

  1. Запустите PowerShell
  2. Перейдите в каталог, который вы хотите проверить на длину пути к файлу (C: works)
  3. Скопируйте и вставьте код [Щелкните правой кнопкой мыши, чтобы вставить в PowerShell, или Alt + Пробел> E> P]
  4. Подождите, пока это не будет сделано, а затем просмотрите файл: cat longfilepath.txt | sort

Объяснение:

Out-File longfilepath.txt ; - создать (или перезаписать) пустой файл с именем 'longfilepath.txt'. Точка с запятой для разделения команд.

cmd /c "dir /b /s /a" | - Запустите команду dir на PowerShell, /a, чтобы показать все файлы, включая скрытые. | к трубе.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} - для каждой строки (обозначается как $ _), если длина больше 250, добавьте эту строку в файл.

2
Rani Kheir

вы можете перенаправить stderr.

больше объяснений здесь , но с такой командой:

MyCommand >log.txt 2>errors.txt

должен получить данные, которые вы ищете.

Кроме того, в качестве хитрости, Windows обходит это ограничение, если путь начинается с префикса \\?\ ( msdn )

Другой трюк, если у вас есть root или назначение, начинающееся с длинного пути, возможно, SUBST поможет:

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 («каталог слишком длинного пути») - это программа, которая спасла меня ... Очень прост в использовании:

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

0
pollaris