2012-01-05 11 views
61

Creé una aplicación que descarga todas las bibliotecas de documentos en un sitio SP, pero en un momento me dio este error (traté de buscar en google pero no pude encontrar nada, ahora si alguien sabe algún truco para resolver este problema por favor responder lo contrario gracias por mirarlo)La mejor manera de resolver la ruta del archivo demasiado tiempo excepción

System.IO.PathTooLongException: La ruta especificada, el nombre de archivo o ambos son demasiado largos. El nombre de archivo completo debe tener menos de 260 caracteres y el nombre del directorio debe tener menos de 248 caracteres. en System.IO.Path.NormalizePathFast (String path, Boolean fullCheck) en System.IO.Path.GetFullPathInternal (ruta de cadena) en System.IO.FileStream.Init (ruta de cadena, modo FileMode, acceso a FileAccess, derechos de Int32 , Boolean useRights, FileShare share, Int32 bufferSize, FileOptions opciones, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromStream) en System.IO.FileStream..ctor (ruta de cadena, modo FileMode, acceso de FileAccess, FileShare share, Int32 bufferSize, opciones de FileOptions) en System.IO.File.Create (string path)

se alcanza el límite de la secuencia, Código es la siguiente,

#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

convertir el UNC (o lo que sea) Ruta en un formato 8.3. [Convertir a formato 8.3 usando CMD] [1] [1]: http://stackoverflow.com/questions/10227144/convert-long-filename-to-short-filename-8 -3-using-cmd-exe – AutomationNation

+0

Posible duplicado de [¿Cómo evitar System.IO.PathTooLongException?] (Http://stackoverflow.com/questions/530109/how-to-avoid-system-io-pathtoolongexception) – Deantwo

Respuesta

46

Como la causa del error es obvio, aquí hay alguna información que debe ayudar a resolver el problema:

ver este MS article about Naming Files, Paths, and Namespaces

He aquí una cita desde el enlace:

Límite máximo de longitud de ruta En la API de Windows (con algunas excepciones tratadas en los párrafos siguientes), la longitud máxima para una ruta es MAX_PATH, que se define como 260 caracteres ters. Una ruta local se estructura en el siguiente orden: letra de unidad, dos puntos, barra inclinada invertida, componentes de nombre separados por barras invertidas y un carácter nulo de terminación . Por ejemplo, la ruta máxima en la unidad D es "D: \ alguno cadena de ruta de 256 caracteres <NUL>" donde "<NUL>" representa el carácter nulo de terminación invisible para la página de códigos del sistema actual. (Los caracteres < > se utilizan aquí para mayor claridad visual y no pueden ser parte de una cadena de ruta válida.)

Y algunas soluciones (tomados de los comentarios):

Hay maneras de resolver los diferentes problemas La idea básica de las soluciones enumeradas a continuación es siempre la misma: reduzca la longitud de la ruta para tener path-length + name-length < MAX_PATH. Usted puede:

  • Compartir una subcarpeta
  • Usar la línea de comandos para asignar una letra de unidad a través de SUBST
  • Uso AddConnection bajo VB para asignar una letra de unidad a un camino
+7

@ TimeToThine, ¿has leído el artículo que publiqué? ¿Leíste los comentarios? Podría estar equivocado, pero no creo que vaya a obtener más ayuda de la comunidad SO, aparte de lo que ya he proporcionado. –

+2

Sí, ya lo leí antes de publicar mi pregunta aquí, incluso probé "\\? \", Pero por alguna razón no funciona en este contexto. Encuentro este blog, usándolo pero por alguna razón no funciona correctamente, "http://www.codinghorror.com/blog/2006/08/shortening-long-file-paths.html" Todavía estoy buscando algo que mantiene el directorio guardado y puedo tomarlo desde allí, o algo así, por ejemplo, usar una etiqueta oculta para guardar el directorio actual en lugar de cadena, pero no estoy seguro de si va a funcionar. –

+4

Es obvio, pero no tiene ningún sentido. ¿Por qué hay una limitación de tamaño de ruta? es 2017. – Jaider

2

En Windows 8.1, utilizando. NET 3.5, tuve un problema similar.
Aunque el nombre de mi archivo tenía solo 239 caracteres de longitud cuando fui a crear una instancia de un objeto FileInfo con solo el nombre del archivo (sin ruta) ocurrió una excepción de tipo 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 

que resuelve el problema recortar el nombre del archivo a 204 caracteres (extensión incluido).

0

Puede crear un enlace simbólico con un directorio más corto. Primero abra la línea de comandos por ejemplo por Shift + RightClick en su carpeta deseada con una ruta más corta (puede que tenga que ejecutarlo como administrador).

continuación, escriba con rutas relativas o absolutas:

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

y luego iniciar la solución de la ruta más corta. La ventaja aquí es: no tienes que mover nada.

-3

Puede reducir el nombre del proyecto en:

Solution Properties -> Application -> Assembly Name 
Cuestiones relacionadas