Pergunta

Estou usando um xcopy em um script do Windows XP para copiar recursivamente um diretório.Continuo recebendo um erro de 'Memória insuficiente', que entendo ser porque um arquivo que estou tentando copiar tem um caminho muito longo.Posso reduzir facilmente o comprimento do caminho, mas infelizmente não consigo descobrir quais arquivos estão violando a restrição de comprimento do caminho.Os arquivos copiados são impressos na saída padrão (que estou redirecionando para um arquivo de log), mas a mensagem de erro é impressa no terminal, então não consigo nem descobrir aproximadamente para qual diretório o erro está sendo fornecido. .

Foi útil?

Solução

faça um dir /s /b > out.txt e então adicione uma guia na posição 260

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

Outras dicas

eu criei a ferramenta Verificador de comprimento de caminho para esse propósito, que é um aplicativo GUI gratuito e agradável que você pode usar para ver o comprimento do caminho de todos os arquivos e diretórios em um determinado diretório.

Eu também escrito e blogado sobre um script simples do PowerShell para obter comprimentos de arquivos e diretórios.Ele produzirá o comprimento e o caminho para um arquivo e, opcionalmente, também o gravará no console.Ele não se limita à exibição de arquivos que têm apenas um determinado comprimento (uma modificação fácil de fazer), mas os exibe em ordem decrescente de comprimento, por isso ainda é muito fácil ver quais caminhos estão acima do seu limite.Aqui está:

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

Como um refinamento da solução mais simples, e se você não pode ou não deseja instalar o Powershell, basta executar:

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

ou (mais rápido):

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

E linhas com mais de 260 chegarão ao topo da lista.Observe que você deve adicionar 1 ao parâmetro da coluna SORT (/+n).

Fiz uma alternativa para as outras boas respostas aqui que usam o PowerShell, mas a minha também salva a lista em um arquivo.Vou compartilhar aqui caso alguém precise de algo assim.

Aviso: O código substitui "longfilepath.txt" no diretório de trabalho atual.Eu sei que é improvável que você já tenha um, mas só para garantir!

Queria propositalmente em uma única linha:

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

Instruções detalhadas:

  1. Execute o PowerShell
  2. Vá até o diretório onde deseja verificar os comprimentos do caminho do arquivo (C:funciona)
  3. Copie e cole o código [Clique com o botão direito para colar no PowerShell ou Alt + Espaço > E > P]
  4. Espere até terminar e visualize o arquivo: cat longfilepath.txt | sort

Explicação:

Out-File longfilepath.txt ; – Crie (ou substitua) um arquivo em branco intitulado 'longfilepath.txt'.Ponto e vírgula para separar comandos.

cmd /c "dir /b /s /a" | – Execute o comando dir no PowerShell, /a para mostrar todos os arquivos, incluindo arquivos ocultos. | para canalizar.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} – Para cada linha (denotada como $_), se o comprimento for maior que 250, anexe essa linha ao arquivo.

você pode redirecionar stderr.

mais explicação aqui, mas tendo um comando como:

MyCommand >log.txt 2>errors.txt

deve pegar os dados que você está procurando.

Além disso, como truque, o Windows ignora essa limitação se o caminho for prefixado com \\?\ (msdn)

Outro truque se você tiver uma raiz ou destino que comece com um caminho longo, talvez SUBST vai ajudar:

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

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

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

a primeira parte apenas percorre esta e subpastas;usando -ErrorVariable AccessDenied significa colocar os itens incorretos na variável do PowerShell AccessDenied.

Você pode então examinar a variável assim

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

Se você não se importa com esses arquivos (pode ser aplicável em alguns casos), simplesmente solte o -ErrorVariable AccessDenied papel.

TLPD (diretório de caminho muito longo ") é o programa que me salvou. Muito fácil de usar:

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

Para caminhos maiores que 260:
você pode usar:

Get-ChildItem | Where-Object {$_.FullName.Length -gt 260}

Exemplo em 14 caracteres:
Para visualizar os comprimentos dos caminhos:

Get-ChildItem | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}

Obtenha caminhos maiores que 14:

Get-ChildItem | Where-Object {$_.FullName.Length -gt 14}  

Captura de tela:
enter image description here

Para nomes de arquivos maiores que 10:

Get-ChildItem | Where-Object {$_.PSChildName.Length -gt 10}

Captura de tela:
enter image description here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top