93

我在 XP windows 脚本中使用 xcopy 递归地复制目录。我不断收到“内存不足”错误,我理解这是因为我尝试复制的文件路径太长。我可以轻松减少路径长度,但不幸的是我无法确定哪些文件违反了路径长度限制。复制的文件被打印到标准输出(我将其重定向到日志文件),但错误消息被打印到终端,所以我什至无法大致确定错误是针对哪个目录给出的.

4

9 回答 9

119

做一个dir /s /b > out.txt然后在位置 260 添加一个指南

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

于 2012-10-02T20:08:33.053 回答
35

为此,我创建了路径长度检查器工具,这是一个不错的免费 G​​UI 应用程序,您可以使用它来查看给定目录中所有文件和目录的路径长度。

我还写过一个关于获取文件和目录长度的简单 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()
于 2013-10-24T23:39:26.490 回答
28

作为最简单解决方案的改进,如果您不能或不想安装 Powershell,只需运行:

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

或(更快):

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

超过 260 的行将排在列表的顶部。请注意,您必须将 1 添加到 SORT 列参数 (/+n)。

于 2016-02-13T15:51:50.540 回答
8

我已经替代了此处使用 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:有效)
  3. 复制粘贴代码【在PowerShell中右键粘贴,或者Alt + Space > E > P】
  4. 等到它完成,然后查看文件:cat longfilepath.txt | sort

解释:

Out-File longfilepath.txt ;– 创建(或覆盖)一个名为“longfilepath.txt”的空白文件。用分号分隔命令。

cmd /c "dir /b /s /a" |– 在 PowerShell 上运行 dir 命令,/a以显示所有文件,包括隐藏文件。|管。

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}– 对于每一行(表示为 $_),如果长度大于 250,则将该行附加到文件中。

于 2016-04-02T21:58:52.180 回答
3

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

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

第一部分只是遍历这个文件夹和子文件夹;using-ErrorVariable AccessDenied意味着将有问题的项目推入 powershell 变量AccessDenied

然后您可以像这样扫描变量

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

如果您不关心这些文件(在某些情况下可能适用),只需删除该-ErrorVariable AccessDenied部分即可。

于 2015-07-20T07:25:27.740 回答
2

您可以重定向标准错误。

更多解释here,但有如下命令:

MyCommand >log.txt 2>errors.txt

应该获取您正在寻找的数据。

此外,作为一个技巧,如果路径以\\?\( msdn )为前缀,Windows 会绕过该限制

如果您有一个以长路径开头的根或目的地,则另一个技巧可能SUBST会有所帮助:

SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D
于 2012-10-03T14:41:25.690 回答
2

TLPD(“太长的路径目录”)是拯救我的程序。非常容易使用:

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

于 2018-06-21T02:21:37.860 回答
0

疯狂地,这个问题仍然是相关的。尽管 E235 给了我基础,但没有一个答案给了我想要的东西。我还打印出名称的长度,以便更容易查看需要修剪的字符数。

Get-ChildItem -Recurse | Where-Object {$_.FullName.Length -gt 260} | %{"{0} : {1}" -f $_.fullname.Length,$_.fullname }
于 2021-11-15T15:43:19.097 回答
-1

对于大于 260 的路径:
您可以使用:

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

14 个字符的示例:
查看路径长度:

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

获取大于 14 的路径:

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

截屏:
在此处输入图像描述

对于大于 10 的文件名:

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

截屏:
在此处输入图像描述

于 2015-03-07T11:05:48.327 回答