फ़ाइल पथ को हल करने का सबसे अच्छा तरीका बहुत लंबा अपवाद है


109

मैंने एक ऐप बनाया है जो एक एसपी साइट में सभी दस्तावेज़ पुस्तकालयों को डाउनलोड करता है, लेकिन एक बिंदु पर यह मुझे यह त्रुटि दे रहा है (मैंने 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 path, FileMode मोड, FileAccess एक्सेस, Int32 राइट्स, Boolean का उपयोग करें) , FileShare share, Int32 बफरसाइज़, FileOptions विकल्प, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) System.IO.FileStream..ctor (स्ट्रिंग पथ, FileMode मोड, FileAccess पहुंच, FileShare साझा, Int32 बफरसाइज़, फ़ाइल विकल्प) पर विकल्प। 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

1
UNC (या जो भी) पथ को 8.3 प्रारूप में परिवर्तित करें। [सीएमडी का उपयोग करके 8.3 प्रारूप में कनवर्ट करें] [1] [१]: stackoverflow.com/questions/10227144/…
ऑटोमेशन


संभव डुप्लिकेट। यहाँ मुझे समाधान stackoverflow.com/a/44211420/5312148
फ्रांसेस्को

जवाबों:


58

जैसा कि त्रुटि का कारण स्पष्ट है, यहाँ कुछ जानकारी है जो आपको समस्या को हल करने में मदद करनी चाहिए:

नामकरण फ़ाइलें, पथ और नाम स्थान के बारे में यह एमएस लेख देखें

यहाँ लिंक से एक उद्धरण है:

अधिकतम पथ लंबाई सीमा विंडोज एपीआई में (कुछ पैराग्राफों में चर्चा किए गए कुछ अपवादों के साथ), एक पथ के लिए अधिकतम लंबाई MAX_PATH है, जिसे 260 वर्णों के रूप में परिभाषित किया गया है। एक स्थानीय पथ को निम्न क्रम में संरचित किया गया है: ड्राइव लेटर, कोलन, बैकस्लैश, बैकस्लैश द्वारा अलग किए गए नाम घटक और एक समाप्ति नल वर्ण। उदाहरण के लिए, ड्राइव D पर अधिकतम पथ "D: \ कुछ 256-वर्ण पथ स्ट्रिंग <NUL>" है, जहां "<NUL>" वर्तमान सिस्टम कोडपेज के लिए अदृश्य समाप्ति शून्य वर्ण का प्रतिनिधित्व करता है। (वर्ण <> यहाँ दृश्य स्पष्टता के लिए उपयोग किए जाते हैं और मान्य पथ स्ट्रिंग का हिस्सा नहीं हो सकते।)

और कुछ वर्कअराउंड (टिप्पणियों से लिया गया):

विभिन्न समस्याओं को हल करने के तरीके हैं। नीचे सूचीबद्ध समाधानों का मूल विचार हमेशा समान है: पथ-लंबाई को कम करने के लिए path-length + name-length < MAX_PATH। आप कर सकते हैं:

  • एक सबफ़ोल्डर साझा करें
  • SUBST के माध्यम से ड्राइव अक्षर निर्दिष्ट करने के लिए कमांडलाइन का उपयोग करें
  • किसी पथ पर ड्राइव अक्षर असाइन करने के लिए VB के अंतर्गत AddConnection का उपयोग करें

7
@TimeToThine, क्या आपने वह लेख पढ़ा है जो मैंने पोस्ट किया था? क्या आपने टिप्पणियों को पढ़ा? मैं गलत हो सकता हूं, लेकिन मुझे नहीं लगता कि आप एसओ समुदाय से कोई और मदद लेने जा रहे हैं, इसके अलावा जो मैंने पहले ही प्रदान किया है।
जेम्स हिल

2
हां, मैंने पहले ही पढ़ लिया था कि यहां अपना प्रश्न पोस्ट करने से पहले, मैंने "\\?" की कोशिश की, लेकिन किसी कारण से इस संदर्भ में काम नहीं किया। मुझे यह ब्लॉग मिल गया है, इसका उपयोग करते हुए लेकिन किसी कारण से इसके ठीक से काम नहीं करने के कारण, " codinghorror.com/blog/2006/08/shortening-long-file-paths.html " अभी भी कुछ ऐसी चीज़ की तलाश में है जो निर्देशिका को सहेज कर रखती है और मैं कर सकता हूँ इसे वहां से ले जाएं, या ऐसा ही कुछ, forexample वर्तमान निर्देशिका को स्ट्रिंग के बजाय सहेजने के लिए एक छिपे हुए लेबल का उपयोग करता है, लेकिन यह सुनिश्चित नहीं है कि यह काम करेगा या नहीं।
मुहम्मद राजा

24
यह स्पष्ट है, लेकिन इसका कोई मतलब नहीं है। क्यों एक पथ-आकार सीमा है ??? यह 2017 है।
जैदर

2
यदि मैंने निर्देशिका की मौजूदा निर्देशिका को निर्देशिका का उपयोग करके फ़ोल्डर की निर्देशिका में बदल दिया है। CetCurrentDirectory () क्या यह प्रतिबंध से बचेगा। या समस्या अभी भी मौजूद होगी।
एडम लिंडसे

3
लेख अद्यतन किया गया लगता है: Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. लेकिन आपको इसे सक्षम करने के लिए एक ऑप्ट-इन और रजिस्ट्री कुंजी सेट करनी होगी।
टॉम डेब्लॉवे

28

मेरे लिए काम करने वाला समाधान रजिस्ट्री कुंजी को लंबे पथ व्यवहार को सक्षम करने के लिए संपादित करना था, मान को 1 पर सेट करना। यह विंडोज 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


2
मैंने इसे 1 पर सेट किया है और अभी भी त्रुटि हो रही है, पता नहीं क्यों इस बिंदु पर।
श्री एंग्री

लेख में दो आवश्यकताओं का उल्लेख है। सबसे पहले रजिस्ट्री कुंजी, और दूसरा आवेदन xml: <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>विजुअल स्टूडियो 2019 में मेरे लिए, विजुअल स्टूडियो को पुनरारंभ करने के बाद यह दूसरी आवश्यकता आवश्यक नहीं थी।
टॉम एंडरसन

मुझे खेद है कि शायद यह बेवकूफी भरा सवाल है लेकिन "एप्लीकेशन xml" क्या है? यह web.config है या कुछ और? मुझे वेब पेज asp.net प्रोजेक्ट पर यह समस्या है
Ondra Starenko

जैसा कि ऊपर कहा गया है, यह एप्लीकेशन एक्सएमएल को बदले बिना विजुअल स्टूडियो 2019 (पुनः आरंभ करने के बाद) में ठीक काम करता है। समाधान के लिए धन्यवाद।
ज़ोमैन

@TomAnderson: मैं VS2017 का उपयोग कर रहा हूं। II को यह एप्लिकेशन कहां मिल सकता है। xml? जैसा कि 1 कदम करने के बाद मेरी समस्या हल नहीं होती है।
शरद

23

जीटा लॉन्ग पाथ्स नामक एक पुस्तकालय है जो लंबे रास्तों के साथ काम करने के लिए एक .NET एपीआई प्रदान करता है।

यहाँ एक अच्छा लेख है जो इस मुद्दे को .NET और PowerShell दोनों के लिए कवर करता है: " .NET, PowerShell Path बहुत लंबा अपवाद और .NET PowerShell Robocopy Clone "


1
अब यह सिर्फ अद्भुत है, और इसका उपयोग करने के लिए कोड को अपडेट करना वास्तव में आसान है। धन्यवाद।
आर्थर

3

आप एक छोटी निर्देशिका के साथ एक प्रतीकात्मक लिंक बना सकते हैं। उदाहरण के लिए पहली ओपन कमांड लाइनShift + RightClick को अपने इच्छित फ़ोल्डर में कम पथ के साथ (आपको इसे व्यवस्थापक के रूप में चलाना पड़ सकता है)।

फिर रिश्तेदार या निरपेक्ष पथ के साथ टाइप करें:

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

और फिर छोटे रास्ते से समाधान शुरू करें। यहाँ लाभ यह है: आपको कुछ भी स्थानांतरित करने की आवश्यकता नहीं है।


यह VS2015 में काम नहीं करता है। ऐसा प्रतीत होता है कि वीएस पथ की लंबाई का प्रसार कर रहा है। VS2015 वर्क-अराउंड के लिए N-Ate उत्तर देखें।
एन-

1
आप क्या कर सकते हैं कमांड "विकल्प" का उपयोग करके ड्राइवर के लिए समाधान फ़ोल्डर को मैप करना है। यह VS2017 के लिए काम करता है।
फ़िलिप कैलासन

2

विंडोज 8.1 पर, का उपयोग कर। NET 3.5, मुझे भी इसी तरह की समस्या थी।
हालाँकि, मेरी फ़ाइल का नाम केवल 239 वर्णों की लंबाई था जब मैं केवल फ़ाइल नाम (पथ के बिना) के साथ एक फ़ाइलइंफो ऑब्जेक्ट को तुरंत टाइप करने के लिए गया था, जो कि टाइप सिस्टम का अपवाद था। 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 वर्ण या उससे कम है।
लॉसबियर

1

यदि आपको लंबे रास्ते के कारण आपकी बिन फ़ाइलों के साथ कोई समस्या हो रही है , तो Visual Studio 2015 में आप आक्रामक प्रोजेक्ट के प्रॉपर्टी पेज पर जा सकते हैं और सापेक्ष आउटपुट निर्देशिका को एक छोटे से बदल सकते हैं।

जैसे बिन \ डिबग \ सी हो जाता है: \ _ बिन्स \ मायप्रोजेक्ट \


1
संपत्तियों को खोलने के बाद जब मेरा निर्माण विफल हो गया तो मैंने देखा कि नया पथ "c: \ vs \ bin \ रिलीज़" को ".. \ _ \ _ \ _ \ _ \ _ \ _ .." के रूप में प्रतिस्थापित किया गया था । । \ vs \ bin \ रिलीज \ " । मुझे यकीन नहीं है कि अगर ".." वर्ण गणना में शामिल हो जाता है।
समिस

2
जिन पथों का मूल्यांकन किया जाता है वे बहुत लंबे रास्ते होते हैं।
N-

1

मेरे लिए जो काम किया गया है वह मेरी परियोजना को आगे बढ़ा रहा है क्योंकि यह डेस्कटॉप पर था (C: \ Users \ lachezar.l \ Desktop \ MyFolder) से (C: \ 0 \ MyFolder) जिसे आप छोटे रास्ते का उपयोग करते हुए देख सकते हैं और इसे हल कर सकते हैं। संकट।


1

मेरे अनुभव से, किसी भी सार्वजनिक सामना करने वाले वेब एप्लिकेशन के लिए मेरे नीचे दिए गए उत्तर की अनुशंसा नहीं करेंगे।

यदि आपको अपने घर के उपकरण या परीक्षण के लिए इसकी आवश्यकता है, तो मैं इसे अपनी मशीन पर साझा करने की सलाह दूंगा।

-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} \ {YourSaredRootDirectory} जैसी साझा निर्देशिका बनाएगा। यह निश्चित रूप से आपके पूर्ण पथ की तुलना में बहुत कम हो सकता है मुझे आशा है, मेरे लिए मैं 290 पात्रों में से 30 पात्रों को कम कर सकता हूं। :)


0

अब तक और एक अद्यतन का उल्लेख नहीं है, बहुत लंबे समय तक पथों को संभालने के लिए एक बहुत अच्छी तरह से स्थापित पुस्तकालय है। AlphaFS एक .NET लाइब्रेरी है जो मानक System.IO कक्षाओं की तुलना में .NET प्लेटफ़ॉर्म को अधिक पूर्ण Win32 फ़ाइल सिस्टम कार्यक्षमता प्रदान करता है। मानक .NET System.IO की सबसे उल्लेखनीय कमी उन्नत NTFS सुविधाओं के समर्थन की कमी है, सबसे विशेष रूप से विस्तारित लंबाई समर्थन (जैसे। फ़ाइल / निर्देशिका पथ 260 वर्णों से अधिक)।


0

सबसे अच्छा जवाब जो मुझे मिल सकता है, यहां टिप्पणियों में से एक में है। इसे उत्तर में जोड़ दें ताकि किसी को टिप्पणी याद न आए और इसे जरूर आजमाएं। इसने मेरे लिए मुद्दा तय कर दिया।

हमें कमांड प्रॉम्प्ट में "विकल्प" कमांड का उपयोग करके ड्राइव फोल्डर को मैप करने की आवश्यकता है- जैसे, विकल्प z:

और फिर इस ड्राइव से समाधान खोलें (इस मामले में जेड)। यह जितना संभव हो उतना छोटा रास्ता तय करेगा और लंबा फ़ाइल नाम समस्या को हल कर सकता है।


0

यह संभवतः समाधान भी हो सकता है। कुछ समय ऐसा भी होता है जब आप अपनी विकास परियोजना को बहुत गहरे में रखते हैं, इसका मतलब संभव हो सकता है परियोजना निर्देशिका में बहुत अधिक निर्देशिकाएं हो सकती हैं, इसलिए कृपया बहुत सारी निर्देशिकाओं को एक साधारण फ़ोल्डर में न रखें। ड्राइव। उदाहरण के लिए- मुझे यह त्रुटि तब भी हो रही थी जब मेरा प्रोजेक्ट इस तरह रखा गया था-

डी: \ शरद \ LatestWorkings \ GenericSurveyApplication020120 \ GenericSurveyApplication \ GenericSurveyApplication

फिर मैंने बस अपने प्रोजेक्ट को पास्ट किया

डी: \ शरद \ LatestWorkings \ GenericSurveyApplication

और समस्या हल हो गई।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.