Come trovo i file con una lunghezza del percorso maggiore di 260 caratteri in Windows?


87

Sto usando un xcopy in uno script di Windows XP per copiare in modo ricorsivo una directory. Continuo a ricevere un errore "Memoria insufficiente", che capisco perché un file che sto cercando di copiare ha un percorso troppo lungo. Posso facilmente ridurre la lunghezza del percorso, ma sfortunatamente non riesco a capire quali file stanno violando la limitazione della lunghezza del percorso. I file che vengono copiati vengono stampati sullo standard output (che sto reindirizzando a un file di registro), ma il messaggio di errore viene stampato sul terminale, quindi non riesco nemmeno a capire approssimativamente per quale directory viene fornito l'errore .


Risposte:


114

fare a dir /s /b > out.txte quindi aggiungere una guida alla posizione 260

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


1
dir / s / b> out.txt fa il lavoro magnificamente. Grazie. "'Get-ChildItem' non è riconosciuto come comando interno o esterno, programma eseguibile o file batch." Immagino di non avere PowerShell.
WestHamster

1
@WestHamster, dovrai eseguire quel comando nella console di PowerShell.
Rami A.

6
Viene visualizzato un errore del tipo: Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.Insieme ad esso, viene stampato solo un percorso abbreviato. ad esempio: D:\Dropbox\ProY...sh._setbinddata. Quelli sono esattamente i percorsi che voglio trovare, ma non riesco a vedere l'intero percorso! Qualche modo per aggirare questo?
MiniGod

Sono l'unico che non riesce a farlo funzionare? Utilizzando Win7 64 bit Home Premium, Powershell 2.0 - quando creo un file di prova con un nome lungo (240 caratteri) e poi rinomino la directory in cui si trova per avere anche un nome lungo, Get-ChildItems -r *smette di vedere il file ... dir /s /bfunziona solo per me.
Jonas Heidelberg

Vedi la mia risposta per un modo per ottenere ciò in PowerShell, che ti consente di trovare i nomi dei file incriminati (quelli sopra i 260 caratteri) o, in alternativa, ignorarli.
Jonno

32

Ho creato lo strumento Path Length Checker per questo scopo, che è una bella app GUI gratuita che puoi usare per vedere le lunghezze del percorso di tutti i file e le directory in una determinata directory.

Ho anche scritto e scritto su un semplice script PowerShell per ottenere lunghezze di file e directory. Produrrà la lunghezza e il percorso di un file e, facoltativamente, lo scriverà anche sulla console. Non si limita a visualizzare i file che superano solo una certa lunghezza (una modifica facile da apportare), ma li visualizza in ordine decrescente in base alla lunghezza, quindi è ancora semplicissimo vedere quali percorsi sono oltre la soglia. Ecco qui:

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

2
Script interessante, ma ricevo ancora questo errore: Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
zkurtz

Strumento eccellente !! Avevo un appuntamento enorme, volevo creare un backup su un disco rigido WD MyCloud. Con questo strumento è venuto a conoscenza della lunghezza massima per creare una struttura di cartelle su HDD. Grazie.
NJMR

Ottimo strumento! L'ho usato per creare uno script in grado di trovare tutti i file / cartelle con un percorso più lungo di 247 caratteri, che è il limite per Synology Drive Client in Windows. Il codice principale è PathLengthChecker.exe RootDirectory="C:\[MyFolder]" MinLength=248, mentre echo SELECT sync_folder FROM session_table;| sqlite3.exe %LocalAppData%\SynologyDrive\data\db\sys.sqliteera necessario per ottenere a livello di codice le cartelle di condivisione. (Se sei interessato al codice completo, non esitare a chiedere)
Kar.ma

Ottimo strumento, grazie. Per il mio lavoro Rsync tra 2 Synology NAS, dovrei conoscere tutti i NOMI FILM più lunghi di 143 caratteri. Questa non è l'intera lunghezza del percorso, è solo la lunghezza massima per nome file. Come posso trovare tali nomi di file?
PeterCo

1
Ehi @PeterCo puoi ancora usare lo script PowerShell sopra, ma invece di usarlo $_.FullNamesostituiscilo con $_.Nameovunque; che ti darà il nome del file invece del percorso completo.
deadlydog

27

Come perfezionamento della soluzione più semplice e se non puoi o non vuoi installare Powershell, esegui:

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

o (più veloce):

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

E le righe più lunghe di 260 arriveranno all'inizio dell'elenco. Tieni presente che devi aggiungere 1 al parametro della colonna SORT (/ + n).


Grazie per la raffinatezza. Nel mio caso non potevo installare Powershell (scatola di Windows 2003). VOTATO UP
preOtep

Puoi spiegare perché devi aggiungere 1 in modo più dettagliato?
Xonatron

C'è un modo per ordinare il file di output in base alla lunghezza della riga?
Xonatron

@Xonatron, "E le linee più lunghe di 260"
cliffclof

Up votato. Penso che questo dovrebbe anche menzionare SUBST per abbreviare un percorso in un'unità ftw.
cliffclof

6

Ho fatto un'alternativa alle altre buone risposte qui che utilizza PowerShell, ma la mia salva anche l'elenco in un file. Lo condividerò qui nel caso in cui qualcun altro abbia bisogno vuole qualcosa del genere.

Avviso: il codice sovrascrive "longfilepath.txt" nella directory di lavoro corrente. So che è improbabile che tu ne abbia già uno, ma per ogni evenienza!

Volutamente voluto in una sola riga:

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

Istruzioni dettagliate:

  1. Esegui PowerShell
  2. Vai alla directory di cui vuoi controllare la lunghezza del percorso del file (C: funziona)
  3. Copia e incolla il codice [Fare clic con il pulsante destro del mouse per incollare in PowerShell o Alt + Spazio> E> P]
  4. Attendi fino al termine e quindi visualizza il file: cat longfilepath.txt | sort

Spiegazione:

Out-File longfilepath.txt ;- Crea (o sovrascrivi) un file vuoto intitolato "longfilepath.txt". Punto e virgola per separare i comandi.

cmd /c "dir /b /s /a" |- Esegui il comando dir su PowerShell, /aper mostrare tutti i file inclusi i file nascosti. |per pipe.

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} - Per ogni riga (indicata come $ _), se la lunghezza è maggiore di 250, aggiungere quella riga al file.


2

puoi reindirizzare stderr.

ulteriori spiegazioni qui , ma con un comando come:

MyCommand >log.txt 2>errors.txt

dovrebbe prendere i dati che stai cercando.

Inoltre, come trucco, Windows ignora tale limitazione se il percorso ha il prefisso \\?\( msdn )

Un altro trucco se hai una radice o una destinazione che inizia con un lungo percorso, forse SUBSTti aiuterà:

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

Reindirizzare l'output std e gli errori dovrebbe darmi un'indicazione abbastanza buona di dove si trova il file grande grazie. comando> file 2> & 1
WestHamster

funzionerà, ma il mio comando dovrebbe separare gli errori in un file separato
SeanC

\\? \ sembra buono anche. Non riesco a far funzionare quanto segue: xcopy / s \\? \ Q: \ nuthatch \\? \ Q: \ finch
WestHamster

hmm ... sembra \\?\ che non funzioni per la riga di comando. Aggiunta un'altra idea utilizzandoSUBST
SeanC

Sfortunatamente subst non sarà troppo utile perché il comando è del tipo: xcopy / sq: \ nuthatch q: \ finch <br/> e il lungo percorso è incorporato da qualche parte sconosciuto sotto il picchio muratore
WestHamster

2

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

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

la prima parte scorre semplicemente attraverso questa e le sottocartelle; using -ErrorVariable AccessDeniedsignifica spingere gli elementi offensivi nella variabile powershell AccessDenied.

È quindi possibile eseguire la scansione della variabile in questo modo

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

Se non ti interessano questi file (potrebbero essere applicabili in alcuni casi), rilascia semplicemente la -ErrorVariable AccessDeniedparte.


Il problema è $_.TargetObjectche non contiene il percorso completo dei file che violano MAX_PATH, solo i nomi delle directory e il nome della directory principale dei file offensivi. Sto lavorando per trovare una soluzione non Robocopy o Subst o Xcopy e pubblicherò quando trovo una soluzione funzionante.
user66001


-2

Per percorsi maggiori di 260:
puoi usare:

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

Esempio su 14 caratteri:
Per visualizzare le lunghezze dei percorsi:

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

Ottieni percorsi maggiori di 14:

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

Immagine dello schermo:
inserisci qui la descrizione dell'immagine

Per i nomi di file maggiori di 10:

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

Immagine dello schermo:
inserisci qui la descrizione dell'immagine


4
Ovviamente non hai idea del problema. Niente di quello che hai suggerito funziona. Si prega di leggere
n0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.