解决文件路径过长异常的最佳方法
本文关键字:最佳 方法 异常 文件 路径 解决 | 更新日期: 2023-09-27 18:19:36
我创建了一个应用程序,可以下载SP站点中的所有文档库,但有一次它给了我这个错误(我试着查看谷歌,但找不到任何东西,现在如果有人知道解决这个问题的技巧,请以其他方式回复,谢谢你的关注)
System.IO.PathTooLongException:指定的路径、文件名或两者都太长。完全限定的文件名必须少于260个字符,目录名必须少于248个字符。位于System.IO.Path.NormalizePathFast(字符串路径,布尔值fullCheck)位于System.IO.Path.GetFullPathInternal(字符串路径)在System.IO.FileStream.Init(字符串路径、文件模式、文件访问、Int32权限、布尔使用权限、文件共享、Int32缓冲区大小、文件选项、SECURITY_ATTRIBUTES secAttrs、字符串消息路径、布尔bFromProxy)在System.IO.FileStream.ctor(字符串路径、FileMode模式、FileAccess访问、FileShare共享、Int32缓冲区大小、FileOptions选项)在System.IO.File.Create(字符串路径)
它达到了字符串的极限,下面给出了代码,
#region Downloading Schemes
private void btnDownload_Click(object sender, EventArgs e)
{
TreeNode currentNode = tvWebs.SelectedNode;
SPObjectData objectData = (SPObjectData)currentNode.Tag;
try
{
CreateLoggingFile();
using (SPWeb TopLevelWeb = objectData.Web)
{
if(TopLevelWeb != null)
dwnEachWeb(TopLevelWeb, TopLevelWeb.Title, tbDirectory.Text);
}
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("Exception caught when tried to pass TopLevelWeb:{1}, Title = {2}, object data to (dwnEachWeb_method), Exception: {0}", ex.ToString(), objectData.Web, objectData.Title));
}
finally
{
CloseLoggingFile();
}
}
private void dwnEachWeb(SPWeb TopLevelWeb, string FolderName, string CurrentDirectory)
{
if (TopLevelWeb != null)
{
if (TopLevelWeb.Webs != null)
{
CurrentDirectory = CurrentDirectory + "''" + TopLevelWeb.Title;
CreateFolder(CurrentDirectory);
foreach (SPWeb ChildWeb in TopLevelWeb.Webs)
{
dwnEachWeb(ChildWeb, ChildWeb.Title, CurrentDirectory);
ChildWeb.Dispose();
}
dwnEachList(TopLevelWeb, CurrentDirectory);
//dwnEachList(TopLevelWeb, FolderName, CurrentDirectory);
}
}
}
private void dwnEachList(SPWeb oWeb, string CurrentDirectory)
{
foreach (SPList oList in oWeb.Lists)
{
if (oList is SPDocumentLibrary && !oList.Hidden)
{
dwnEachFile(oList.RootFolder, CurrentDirectory);
}
}
}
private void dwnEachFile(SPFolder oFolder, string CurrentDirectory)
{
if (oFolder.Files.Count != 0)
{
CurrentDirectory = CurrentDirectory + "''" + oFolder.Name;
CreateFolder(CurrentDirectory);
foreach (SPFile ofile in oFolder.Files)
{
if (CreateDirectoryStructure(CurrentDirectory, ofile.Url))
{
var filepath = System.IO.Path.Combine(CurrentDirectory, ofile.Url);
byte[] binFile = ofile.OpenBinary();
System.IO.FileStream fstream = System.IO.File.Create(filepath);
fstream.Write(binFile, 0, binFile.Length);
fstream.Close();
}
}
}
}
//creating directory where files will be download
private bool CreateDirectoryStructure(string baseFolder, string filepath)
{
if (!Directory.Exists(baseFolder)) return false;
var paths = filepath.Split('/');
for (var i = 0; i < paths.Length - 1; i++)
{
baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
Directory.CreateDirectory(baseFolder);
}
return true;
}
//creating folders
private bool CreateFolder(string CurrentDirectory)
{
if (!Directory.Exists(CurrentDirectory))
{
Directory.CreateDirectory(CurrentDirectory);
}
return true;
}
//shorting string
#endregion
由于错误的原因很明显,以下是一些可以帮助您解决问题的信息:
请参阅这篇关于命名文件、路径和命名空间的MS文章
以下是链接中的一句话:
最大路径长度限制在Windows API中(以下段落中讨论了一些例外情况)路径为MAX_path,定义为260个字符。当地人路径的结构顺序如下:驱动器号、冒号、,反斜杠、用反斜杠分隔的名称组件和终止null字符。例如,驱动器D上的最大路径为"D:''some256个字符的路径字符串<NUL>"where"<NUL>"代表看不见的终止当前系统代码页的空字符。(字符<gt;此处用于视觉清晰度,不能作为有效的路径字符串。)
还有一些变通办法(摘自评论):
有办法解决各种各样的问题。下面列出的解决方案的基本思想始终相同:减少路径长度以获得path-length + name-length < MAX_PATH
。您可以:
- 共享子文件夹
- 使用命令行通过SUBST分配驱动器号
- 在VB下使用AddConnection为路径分配驱动器号
对我有效的解决方案是编辑注册表项以启用长路径行为,将值设置为1。这是Windows 10 的一个新的选择加入功能
HKLM'SYSTEM'CurrentControlSet'Control'FileSystem LongPathsEnabled (Type: REG_DWORD)
我从@jameshill发布的文章的一个命名部分得到了这个解决方案。
命名文件、路径和命名空间:最大路径长度限制
在Windows 10版本1607之前的Windows版本中,路径的最大长度为MAX_path,定义为260个字符。在更高版本的Windows中,需要更改注册表项或使用组策略工具来删除限制。有关详细信息,请参阅最大路径长度限制。
另请参阅@dontbyteme提到的最大路径长度限制。
要启用新的长路径行为,必须满足以下两个条件:
- 注册表项
Computer'HKEY_LOCAL_MACHINE'SYSTEM'CurrentControlSet'Control'FileSystem'LongPathsEnabled (Type: REG_DWORD)
必须存在并设置为1。在第一次调用受影响的Win32文件或目录函数后,系统(每个进程)将缓存键的值(请参阅下面的函数列表)。在进程的生存期内,不会重新加载注册表项。为了让系统上的所有应用程序都能识别密钥的值,可能需要重新启动,因为某些进程可能在设置密钥之前就已经启动了- 应用程序清单还必须包括
longPathAware
元素<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
有一个名为Zeta Long Paths的库,它提供了一个.NET API来处理长路径。
这是一篇很好的文章,涵盖了.NET和PowerShell的这个问题:".NET,PowerShell Path too Long Exception and a.NET PowerShell Robocopy Clone"
您可以创建一个具有较短目录的符号链接。首先打开命令行,例如通过Shift + RightClick
打开所需文件夹中的较短路径(您可能必须以管理员身份运行它)。
然后键入相对路径或绝对路径:
mklink ShortPath'To'YourLinkedSolution C:'Path'To'Your'Solution /D
然后从较短的路径启动解决方案。这里的优点是:你不需要移动任何东西。
对我有用的是将我的项目从桌面上的位置(C:''Users''lachezar.l''desktop''MyFolder)移动到(C:''0''MyFolder),正如你所看到的,它使用了更短的路径并减少了路径,解决了问题。
在Windows 8.1上,使用。NET 3.5,我也遇到了类似的问题
虽然当我用文件名(没有路径)实例化FileInfo对象时,我的文件名只有239个字符长,但发生了System类型的异常。IO.PathTooLongException
2014-01-22 11:10:35 DEBUG LogicalDOCOutlookAddIn.LogicalDOCAddIn - fileName.Length: 239
2014-01-22 11:10:35 ERROR LogicalDOCOutlookAddIn.LogicalDOCAddIn - Exception in ImportEmail System.IO.PathTooLongException: Percorso e/o nome di file specificato troppo lungo. Il nome di file completo deve contenere meno di 260 caratteri, mentre il nome di directory deve contenere meno di 248 caratteri.
in System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)
in System.IO.FileInfo..ctor(String fileName)
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.GetTempFilePath(String fileName) in C:'Users'alle'Documents'Visual Studio 2010'Projects'MyAddin1Outlook20072010'MyAddin1Outlook20072010'LogicalDOCAddIn.cs:riga 692
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmail(_MailItem mailItem, OutlookConfigXML configXML, Int64 targetFolderID, String SID) in C:'Users'alle'Documents'Visual Studio 2010'Projects'MyAddin1Outlook20072010'MyAddin1Outlook20072010'LogicalDOCAddIn.cs:riga 857
in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmails(Explorers explorers, OutlookConfigXML configXML, Int64 targetFolderID, Boolean suppressResultMB) in C:'Users'alle'Documents'Visual Studio 2010'Projects'MyAddin1Outlook20072010'MyAddin1Outlook20072010'LogicalDOCAddIn.cs:riga 99
我解决了将文件名修剪为204个字符(包括扩展名)的问题。
如果您的bin文件由于路径长而出现问题,在Visual Studio 2015中,您可以转到有问题的项目的属性页,并将相对的输出目录更改为较短的目录。
例如,bin''debug''变成C:''_bins''MyProject''
更不用说目前为止的更新了,有一个非常好的库可以处理太长的路径。AlphaFS是一个.NET库,它为.NET平台提供了比标准system.IO类更完整的Win32文件系统功能。标准.NET System.IO最显著的不足是缺乏对高级NTFS功能的支持,尤其是对扩展长度路径的支持(例如,文件/目录路径长度超过260个字符)。
我能找到的最好的答案是在这里的一条评论中。将其添加到答案中,这样就不会有人错过评论,并且肯定应该尝试一下。它为我解决了这个问题。
我们需要使用命令提示符中的"subst"命令将解决方案文件夹映射到驱动器-例如,subst z:
然后从此驱动器打开解决方案(在本例中为z)。这将尽可能缩短路径,并可以解决冗长的文件名问题。
根据我的经验,我不建议任何面向公众的Web应用程序使用以下答案。
如果您的内部工具或测试需要它,我建议您在自己的机器上共享它。
-Right click on the root path you need to access
-Choose Properties
-Click on Share button and add your chosen users who can access it
这将创建一个共享目录,如''''{PCName}''{YourSharedRootDirectory}这肯定比你的完整路径要少得多,我希望,对我来说,我可以从大约290个字符减少到30个字符。:)
这也可能是解决方案。有时,当你把开发项目放得太深时,也会发生这种情况,这意味着项目目录可能有太多目录,所以请不要让太多目录把它放在驱动器内的一个简单文件夹中。例如,当我的项目保持这样时,我也遇到了这个错误-
D: ''Sharad''LatestWorkings''GenericSurveyApplication020120''GenericSurveyApplication''GenericSurveyApplication
然后我简单地将我的项目粘贴到中
D: ''Sharad''LatestWorkings''GenericSurveyApplication
问题解决了。
针对.NET Framework 4.6.2及更高版本的应用程序Long默认情况下支持路径。运行时抛出以下条件下的PathTooLongException:
- 操作系统返回COR_E_PATHTOOLONG或其等效值
- 路径的长度超过Int16.最大值(32767)个字符
https://learn.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception?view=net-6.0
以下内容与我一起使用visual studio 2022在Windows 10上工作:
运行以下powershell脚本:
New ItemProperty-Path";HKLM:''SYSTEM''CurrentControlSet''Control''FileSystem"-名称";LongPathsEnabled"-值1-属性类型DWORD-强制
重新启动电脑,再次运行visualstudio。
如果您不想更改注册表,请将项目移动到较短路径的目标位置。