我在 XP Windows 脚本中使用 xcopy 命令来递归地复制一个目录,但是一直收到“内存不足”错误提示。我了解这是因为我正在尝试复制的某个文件路径太长了。我可以很容易地缩短路径长度,但不幸的是,我无法确定哪些文件违反了路径长度限制。被复制的文件会输出到标准输出(我将其重定向到日志文件),但错误消息会打印到终端上,因此我甚至无法大致确定给出错误信息的目录。
我在 XP Windows 脚本中使用 xcopy 命令来递归地复制一个目录,但是一直收到“内存不足”错误提示。我了解这是因为我正在尝试复制的某个文件路径太长了。我可以很容易地缩短路径长度,但不幸的是,我无法确定哪些文件违反了路径长度限制。被复制的文件会输出到标准输出(我将其重定向到日志文件),但错误消息会打印到终端上,因此我甚至无法大致确定给出错误信息的目录。
执行 dir /s /b > out.txt
命令,然后在 260 位置添加一个指南。
在 PowerShell 中使用 cmd /c dir /s /b |? {$_.length -gt 260}
命令。
Get-ChildItem : 指定的路径、文件名或两者都太长。完全限定的文件名必须少于 260 个字符,目录名必须少于 248 个字符。
同时只有缩短后的路径被打印出来,例如 D:\Dropbox\ProY...sh._setbinddata
。这些正是我想要查找的路径,但我无法看到整个路径!有什么解决办法吗? - MiniGod我为此创建了路径长度检查器工具,这是一个漂亮的免费GUI应用程序,您可以使用它来查看给定目录中所有文件和目录的路径长度。
我还编写并发布了一个简单的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()
Get-ChildItem:指定的路径、文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名必须少于248个字符。
- zkurtzPathLengthChecker.exe RootDirectory="C:\[MyFolder]" MinLength=248
,而需要使用echo SELECT sync_folder FROM session_table;| sqlite3.exe %LocalAppData%\SynologyDrive\data\db\sys.sqlite
来以编程方式获取共享文件夹。(如果您对完整代码有兴趣,请随时询问。) - Kar.ma$_.FullName
,而应该在所有地方替换为$_.Name
;这将给你文件名而不是完整路径。 - deadlydog如果你不能或不想安装PowerShell,可以采用简单解决方案的改进版本,只需运行:
dir /s /b | sort /r /+261 > out.txt
dir /s /b | sort /r /+261 /o out.txt
注意,长度超过260个字符的行将排在列表的顶部。请注意,在SORT列参数中必须添加1(/+n)。
Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}
详细说明:
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,则将该行追加到文件中。
来源于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
部分即可。$_.TargetObject
中不包含违反MAX_PATH
的文件的完整路径,只有目录名称和有问题文件的父目录名称。我正在寻找一个非Robocopy或Subst或Xcopy的解决方案,并将在找到可行解决方案后发布。 - user66001令人惊讶的是,这个问题仍然很重要。虽然E235给了我基础,但没有一个答案完全符合我的要求。我还打印出名称的长度,以便更容易地看到需要修剪多少个字符。
Get-ChildItem -Recurse | Where-Object {$_.FullName.Length -gt 260} | %{"{0} : {1}" -f $_.fullname.Length,$_.fullname }
\\?\
在命令行中不起作用。添加了另一个使用SUBST
的想法。 - SeanC对于路径大于260个字符的情况:
您可以使用:
Get-ChildItem | Where-Object {$_.FullName.Length -gt 260}
14 个字符的示例:
查看路径长度的方法:
Get-ChildItem | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}
Get-ChildItem | Where-Object {$_.FullName.Length -gt 14}
截图:
对于文件名大于10个字符的情况:
Get-ChildItem | Where-Object {$_.PSChildName.Length -gt 10}
截图: