c# - 解决文件路径过长异常的最佳方法

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

System.IO.PathTooLongException:指定的路径,文件名或两者都太长。 完全限定的文件名必须少于260个字符,目录名必须少于248个字符。      在System.IO.Path.NormalizePathFast(String path,Boolean fullCheck)      在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)      在System.IO.FileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享,Int32 bufferSize,FileOptions选项)      在System.IO.File.Create(String path)

它达到字符串的限制,代码如下,

#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
Muhammad Raja asked 2019-09-10T09:27:28Z
9个解决方案
51 votes

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

请参阅此MS文章,了解命名文件,路径和命名空间

以下是该链接的引用:

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

以及一些解决方法(摘自评论):

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

  • 共享一个子文件夹
  • 使用命令行通过SUBST分配驱动器号
  • 在VB下使用AddConnection为路径分配驱动器号
James Hill answered 2019-09-10T09:28:35Z
23 votes

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

这是一篇很好的文章,涵盖.NET和PowerShell的这个问题:“.NET,PowerShell路径太长的异常和.NET PowerShell Robocopy克隆”

Tim Lewis answered 2019-09-10T09:29:05Z
8 votes

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

goonerify answered 2019-09-10T09:29:49Z
2 votes

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

Marcel Piquet answered 2019-09-10T09:30:26Z
2 votes

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

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

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

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

Markus Weber answered 2019-09-10T09:31:03Z
1 votes

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

例如。 bin \ debug \成为C:\ _ bins \ MyProject \

N-ate answered 2019-09-10T09:31:33Z
1 votes

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

Lachezar Lalov answered 2019-09-10T09:31:57Z
0 votes

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

Markus Hooge answered 2019-09-10T09:32:21Z
-6 votes

您可以在以下位置减少项目名称:

Solution Properties -> Application -> Assembly Name
Pauly Garcia answered 2019-09-10T09:32:46Z
translate from https://stackoverflow.com:/questions/8745215/best-way-to-resolve-file-path-too-long-exception