121

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

System.IO.PathTooLongException:指定的路径、文件名或两者都太长。完全限定的文件名必须少于 260 个字符,目录名必须少于 248 个字符。在 System.IO.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.GetFullPathInternal(String path) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights , FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at 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
4

12 回答 12

66

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

请参阅这篇关于命名文件、路径和命名空间的 MS 文章

这是链接中的引述:

最大路径长度限制在 Windows API 中(以下段落中讨论了一些例外情况),路径的最大长度为 MAX_PATH,定义为 260 个字符。本地路径按以下顺序构造:驱动器号、冒号、反斜杠、由反斜杠分隔的名称组件和终止空字符。例如,驱动器 D 上的最大路径是“D:\some 256-character path string<NUL>”,其中“<NUL>”表示当前系统代码页的不可见终止空字符。(字符 < > 在此处用于视觉清晰,不能作为有效路径字符串的一部分。)

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

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

  • 共享子文件夹
  • 使用命令行通过 SUBST 分配驱动器号
  • VB下使用AddConnection给路径分配盘符
于 2012-01-05T15:44:51.813 回答
41

对我有用的解决方案是编辑注册表项以启用长路径行为,将值设置为 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

于 2018-10-12T11:41:37.940 回答
25

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

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

于 2013-01-13T19:01:56.737 回答
8

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

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

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

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

于 2017-06-17T10:11:35.497 回答
3

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

于 2018-06-22T14:23:45.273 回答
2

在 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 个字符(包括扩展名)的问题。

于 2014-01-22T10:39:41.383 回答
1

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

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

于 2018-03-12T19:44:15.823 回答
1

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

于 2019-02-25T16:07:37.253 回答
0

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

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

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

于 2019-04-30T05:47:16.967 回答
0

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

于 2019-07-15T16:48:31.037 回答
0

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

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

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

D:\Sharad\LatestWorkings\GenericSurveyApplication

问题解决了。

于 2020-01-07T06:01:39.630 回答
0

面向 .NET Framework 4.6.2 及更高版本的应用程序默认支持长路径。在以下情况下,运行时会引发 PathTooLongException:

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

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

于 2022-01-27T09:13:13.080 回答