Подтвердить что ты не робот

Лучший способ разрешить путь к файлу слишком долгое исключение

Я создал приложение, которое загружает все библиотеки документов на SP-сайте, но однажды сообщило мне об этой ошибке (я попытался взглянуть на google, но не смог найти ничего, теперь, если кто-нибудь знает какой-либо трюк для решения этой проблемы, пожалуйста, ответьте иначе спасибо за то, что посмотрели)

System.IO.PathTooLongException: указанный путь, имя файла или оба слишком длинны. Полноценное имя файла должно быть менее 260 символов, а имя каталога должно быть меньше 248 символов.    в System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)    в System.IO.Path.GetFullPathInternal(String path)    в System.IO.FileStream.Init(путь String, режим FileMode, доступ к FileAccess, права Int32, логические useRights, общий ресурс FileShare, параметры Int32 bufferSize, FileOptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)    в System.IO.FileStream..ctor(путь String, режим 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
4b9b3361

Ответ 1

Как причина ошибки очевидна, вот некоторая информация, которая поможет вам решить проблему:

См. статью MS об именах файлов, путей и пространства имен

Здесь цитата из ссылки:

Ограничение максимальной длины пути В API Windows (с некоторыми исключениями, описанными в следующих параграфах) максимальная длина для пути MAX_PATH, который определяется как 260 символов. Местный путь структурирован в следующем порядке: буква диска, двоеточие, обратная косая черта, компоненты имени, разделенные обратными косыми чертами, и завершение null знак. Например, максимальный путь на диске D равен "D:\some 256-символьная строка пути <NUL> " where "<NUL> " представл ет невидимый завершающий нулевой символ для текущей кодовой страницы системы. (The символы < > используются для визуальной ясности и не могут быть частью допустимая строка пути.)

И несколько обходных решений (взятых из комментариев):

Есть способы решить различные проблемы. Основная идея перечисленных ниже решений всегда одинакова: уменьшите длину пути, чтобы иметь path-length + name-length < MAX_PATH. Вы можете:

  • Поделитесь вложенной папкой
  • Используйте командную строку для назначения буквы диска с помощью SUBST
  • Используйте AddConnection под VB, чтобы назначить букву диска пути

Ответ 3

Решение, которое работало для меня, состояло в том, чтобы отредактировать ключ реестра, чтобы включить поведение длинного пути, установив значение 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

Ответ 4

В Windows 8.1, используя .NET 3.5, у меня была аналогичная проблема.
Хотя имя моего файла было всего 239 символов, когда я отправился создавать экземпляр объекта FileInfo только с именем файла (без пути), произошло исключение типа 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 символа (расширение включено).

Ответ 5

Вы можете создать символическую ссылку с более коротким каталогом. Сначала открыть командную строку, например, Shift + RightClick в вашей желаемой папке с более коротким путем (возможно, вам придется запускать ее как администратор).

Затем введите относительные или абсолютные пути:

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

И затем запустите решение из более короткого пути. Преимущество здесь: вам не нужно ничего перемещать.

Ответ 6

Если у вас возникла проблема с файлами bin из-за длинного пути, в Visual Studio 2015 вы можете перейти на страницу свойств проекта, который нарушил работу, и изменить относительный каталог вывода на более короткий.

Например, bin\debug \ становится C:\_ bins\MyProject \

Ответ 7

Для меня сработало то, что мой проект был перенесен на рабочий стол (C:\Users\lachezar.l\Desktop\MyFolder) в (C:\0\MyFolder), который, как вы можете видеть, использует более короткий путь. проблема.

Ответ 8

Пока не упомянуто и об обновлении, есть очень хорошо разработанная библиотека для обработки слишком длинных путей. AlphaFS - это библиотека .NET, предоставляющая более полную функциональность файловой системы Win32 для платформы .NET, чем стандартные классы System.IO. Наиболее заметным недостатком стандартного .NET System.IO является отсутствие поддержки расширенных функций NTFS, в частности, поддержка расширенных путей (например, пути к файлам/каталогам длиннее 260 символов).

Ответ 9

Лучший ответ, который я могу найти, находится в одном из комментариев здесь. Добавьте его к ответу, чтобы кто-то не пропустил комментарий и обязательно попробовал это. Это исправило проблему для меня.

Нам нужно сопоставить папку решения с диском, используя команду "subst" в команде prompt-, например, subst z:

Затем откройте решение с этого диска (в данном случае z). Это максимально сократило бы путь и могло бы решить проблему длинного имени файла.

Ответ 10

Исходя из моего опыта, я не буду рекомендовать мой ответ ниже для любых общедоступных веб-приложений.

Если вам это нужно для собственных инструментов или для тестирования, я бы порекомендовал поделиться им на своем компьютере.

-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} Это, безусловно, может быть намного меньше, чем ваш полный путь, я надеюсь, для себя я мог бы сократить до 30 символов с 290 символов. :)

Ответ 11

Вы можете уменьшить название проекта в:

Solution Properties -> Application -> Assembly Name