【问题标题】:Best way to resolve file path too long exception解决文件路径太长异常的最佳方法
【发布时间】:2012-01-05 15:39:56
【问题描述】:

我创建了一个应用程序,可以下载 SP 站点中的所有文档库,但有一次它给了我这个错误(我尝试查看谷歌但找不到任何东西,现在如果有人知道解决这个问题的任何技巧,请否则回复感谢您查看它)

System.IO.PathTooLongException:指定的路径、文件名或两者都太长。完全限定的文件名必须少于 260 个字符,目录名必须少于 248 个字符。 在 System.IO.Path.NormalizePathFast(字符串路径,布尔 fullCheck) 在 System.IO.Path.GetFullPathInternal(字符串路径) 在 System.IO.FileStream.Init(字符串路径,FileMode 模式,FileAccess 访问,Int32 权限,布尔用户权限,文件共享共享,Int32 缓冲区大小,FileOptions 选项,SECURITY_ATTRIBUTES secAttrs,字符串 msgPath,布尔 bFromProxy) 在 System.IO.FileStream..ctor(字符串路径、FileMode 模式、FileAccess 访问、FileShare 共享、Int32 bufferSize、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

【问题讨论】:

标签: c# .net string file sharepoint


【解决方案1】:

由于错误原因很明显,这里有一些信息可以帮助您解决问题:

看到这个MS article about Naming Files, Paths, and Namespaces

这是来自链接的引述:

最大路径长度限制 路径是 MAX_PATH,定义为 260 个字符。本地人 路径按以下顺序构建:驱动器号、冒号、 反斜杠,由反斜杠分隔的名称组件和终止 空字符。例如,驱动器 D 上的最大路径是“D:\some 256 个字符的路径字符串”,其中“”表示不可见 当前系统代码页的终止空字符。 (这 字符 在这里用于视觉清晰,不能成为 一个有效的路径字符串。)

还有一些解决方法(取自 cmets):

有很多方法可以解决各种问题。下面列出的解决方案的基本思想始终相同:减少路径长度以获得path-length + name-length &lt; MAX_PATH。你可以:

  • 共享子文件夹
  • 使用命令行通过 SUBST 分配驱动器号
  • VB下使用AddConnection为路径分配盘符

【讨论】:

  • @TimeToThine,你读过我发布的文章吗?你读过cmets吗?我可能是错的,但我认为你不会从 SO 社区获得更多帮助,除了我已经提供的帮助。
  • 是的,我在这里发布我的问题之前已经阅读过,我什至尝试过 "\\?\" 但由于某种原因它在这种情况下不起作用。我找到了这个博客,正在使用它,但由于某种原因它不能正常工作,“codinghorror.com/blog/2006/08/shortening-long-file-paths.html”我仍在寻找可以保存目录的东西,我可以从那里获取它,或者类似的东西,例如使用隐藏标签保存当前目录而不是字符串,但不确定它是否会起作用。
  • 这很明显,但没有任何意义。为什么有路径大小限制???现在是 2017 年。
  • 如果我使用 Directory.SetCurrentDirectory() 将当前目录更改为文件夹的目录,是否会避免此限制。或者问题仍然存在。
  • 文章好像已经更新了:Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. 但是你必须选择加入,并设置一个注册表项来启用它。
【解决方案2】:

对我有用的解决方案是编辑注册表项以启用长路径行为,将值设置为 1。这是 Windows 10 的新选择加入功能

HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)

我从@james-hill 发布的文章的指定部分获得了这个解决方案。

https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

【讨论】:

  • 我已将此设置为 1,但仍然出现错误,此时不知道为什么。
  • 文章提到了两个要求。首先是注册表项,其次是应用程序 xml:&lt;application xmlns="urn:schemas-microsoft-com:asm.v3"&gt; &lt;windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings"&gt; &lt;ws2:longPathAware&gt;true&lt;/ws2:longPathAware&gt; &lt;/windowsSettings&gt; &lt;/application&gt; 对于 Visual Studio 2019 中的我来说,重启 Visual Studio 后不需要第二个要求。
  • 对不起,这可能是个愚蠢的问题,但什么是“应用程序 xml”?是 web.config 还是别的什么?我在网页 asp.net 项目中遇到了这个问题
  • @OndraStarenko xml 在应用程序清单文件中。有关更多信息,请参阅Application Manifests。您需要将longPathAware 添加到应用程序的清单文件中。例如,如果您在 Visual Studio 中从 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 打开 PowerShell.exe,则可以查看应用程序清单。并在 exe 中查看此设置。
  • 链接到汤姆安德森提到的更多细节:docs.microsoft.com/de-de/windows/win32/fileio/…
【解决方案3】:

有一个名为 Zeta Long Paths 的库,它提供了一个 .NET API 来处理长路径。

这是一篇很好的文章,涵盖了 .NET 和 PowerShell 的这个问题:“.NET, PowerShell Path too Long Exception and a .NET PowerShell Robocopy Clone

【讨论】:

  • 现在这真是太棒了,而且很容易更新使用它的代码。谢谢。
【解决方案4】:

您可以使用较短的目录创建符号链接。 首先打开命令行,例如通过Shift + RightClick 在您想要的文件夹中使用较短的路径(您可能必须以管理员身份运行它)。

然后输入相对或绝对路径:

mklink ShortPath\To\YourLinkedSolution C:\Path\To\Your\Solution /D

然后从较短的路径开始解决方案。这里的优点是:您不必移动任何东西。

【讨论】:

  • 这在 VS2015 中不起作用。看起来 VS 正在预先验证路径的长度。有关 VS2015 解决方法,请参阅 N-Ate 答案。
  • 您可以使用命令“subst”将解决方案文件夹映射到驱动程序。这适用于 VS2017。
  • 更简单、更客观。谢谢!
【解决方案5】:

对我有用的是将我的项目在桌面 (C:\Users\lachezar.l\Desktop\MyFolder) 上移动到 (C:\0\MyFolder),如您所见,它使用更短的路径并减少它解决了这个问题。

【讨论】:

    【解决方案6】:

    在 Windows 8.1 上,使用。 NET 3.5,我遇到了类似的问题。
    虽然我的文件名只有 239 个字符长度,但当我用文件名(不带路径)实例化 FileInfo 对象时,却发生了 System.Exception 类型的异常。 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 个字符(包括扩展名)的问题。

    【讨论】:

    • 阅读此内容的任何人的附加信息 - 文件名限制为 247 个字符,而完整路径限制为 259 个。因此,如果您的文件名是 239,则路径的其余部分只剩下 20 个字符(例如“c:\temp”)。如果修剪文件名,则需要确保完整路径不超过 259 个字符。
    【解决方案7】:

    如果您的 bin 文件由于路径过长而出现问题,在 Visual Studio 2015 中,您可以转到有问题的项目的属性页并更改相对 输出目录 变短。

    例如bin\debug\ 变为 C:\_bins\MyProject\

    【讨论】:

    • 在我的构建失败时重新打开属性后,我注意到新路径 "c:\vs\bin\Release" 被替换为 "..\。 .\..\..\..\..\..\..\vs\bin\Release\".我不确定 "..\" 是否会计入字符数。
    • 被评估为太长的路径是绝对路径。
    【解决方案8】:

    到目前为止没有提及更新,有一个非常完善的库来处理太长的路径。 AlphaFS 是一个 .NET 库,为 .NET 平台提供比标准 System.IO 类更完整的 Win32 文件系统功能。标准 .NET System.IO 最显着的缺陷是缺乏对高级 NTFS 功能的支持,尤其是对扩展长度路径的支持(例如,文件/目录路径超过 260 个字符)。

    【讨论】:

      【解决方案9】:

      我能找到的最佳答案是在这里的其中一个 cmets 中。 将其添加到答案中,以便有人不会错过评论,并且绝对应该尝试一下。它为我解决了这个问题。

      我们需要使用命令提示符中的“subst”命令将解决方案文件夹映射到驱动器 - 例如,subst z:

      然后从该驱动器(在本例中为 z)打开解决方案。这将尽可能缩短路径,并可以解决冗长的文件名问题。

      【讨论】:

        【解决方案10】:

        根据我的经验,对于任何面向公众的 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 个字符。 :)

        【讨论】:

          【解决方案11】:

          这也可能是解决方案。有时当您将开发项目保持得太深时也会发生这种情况,这意味着可能项目目录可能有太多目录所以请不要让太多目录保持简单驱动器内的文件夹。例如-当我的项目保持这样时,我也遇到了这个错误-

          D:\Sharad\LatestWorkings\GenericSurveyApplication020120\GenericSurveyApplication\GenericSurveyApplication

          然后我只是将我的项目粘贴到里面

          D:\Sharad\LatestWorkings\GenericSurveyApplication

          问题就解决了。

          【讨论】:

            【解决方案12】:

            面向 .NET Framework 4.6.2 及更高版本的应用 Long 默认支持路径。运行时抛出一个 PathTooLongException 在以下情况下:

            • 操作系统返回 COR_E_PATHTOOLONG 或其等效项。
            • 路径长度超过 Int16.MaxValue (32,767) 个字符。

            https://docs.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception?view=net-6.0

            【讨论】:

              猜你喜欢
              • 2011-01-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多