c# - rutas - La mejor forma de resolver la ruta del archivo es una excepción demasiado larga
porque me dice que el nombre es demasiado largo (7)
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 conoce algún truco para resolver este problema, responda lo contrario) para mirarlo)
System.IO.PathTooLongException: la ruta especificada, el nombre del 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 (String path) en System.IO.FileStream.Init (String path, modo FileMode, acceso a FileAccess, derechos Int32, boolean useRights , FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromStream) en System.IO.FileStream..ctor (ruta de cadena, modo FileMode, acceso de FileAccess, recurso compartido FileShare, Int32 bufferSize, opciones de FileOptions) en System. IO.File.Create (Ruta de cadena)
alcanza el límite para la cadena, el código se da a continuación,
#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
Como la causa del error es obvia, aquí hay información que debería ayudarlo a resolver el problema:
Consulte este artículo de MS sobre nombres de archivos, rutas y espacios de nombres
Aquí hay una cita del enlace:
Límite máximo de longitud de ruta En la API de Windows (con algunas excepciones que se analizan en los párrafos siguientes), la longitud máxima de una ruta es MAX_PATH, que se define como 260 caracteres. Una ruta local está estructurada en el siguiente orden: letra de unidad, dos puntos, barra 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: / alguna 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 claridad visual y no pueden ser parte de una cadena de ruta válida.)
Y algunas soluciones (tomadas de los comentarios):
Hay formas de resolver los diversos 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
. Puedes:
- Comparte una subcarpeta
- Use la línea de comando para asignar una letra de unidad mediante SUBST
- Use AddConnection en VB para asignar una letra de unidad a una ruta
En Windows 8.1, usando. NET 3.5, tuve un problema similar.
Aunque el nombre de mi archivo tenía solo 239 caracteres de longitud cuando fui a instanciar 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
Resolví el problema de recortar el nombre del archivo a 204 caracteres (extensión incluida).
Hay una biblioteca llamada Zeta Long Paths que proporciona una API .NET para trabajar con rutas largas.
Aquí hay un buen artículo que cubre este tema para .NET y PowerShell: " .NET, PowerShell Path too Exception y un clon de .NET PowerShell Robocopy "
Lo que funcionó para mí es mover mi proyecto como estaba en el escritorio (C: / Users / lachezar.l / Desktop / MyFolder) a (C: / 0 / MyFolder) que, como puede ver, utiliza una ruta más corta y reduciendo el problema. problema.
Puede crear un enlace simbólico con un directorio más corto. Primero abra la línea de comando, por ejemplo, con la Shift + RightClick
en la carpeta deseada con una ruta más corta (es posible que deba ejecutarla como administrador).
Luego escribe con rutas relativas o absolutas:
mklink ShortPath/To/YourLinkedSolution C:/Path/To/Your/Solution /D
Y luego inicie la Solución desde la ruta más corta. La ventaja aquí es: no tienes que mover nada.
Puede reducir el nombre del proyecto en:
Solution Properties -> Application -> Assembly Name
Si tiene un problema con sus archivos bin debido a una ruta larga, en Visual Studio 2015 puede ir a la página de propiedades del proyecto infractor y cambiar el directorio de salida relativo por uno más corto.
Por ejemplo, bin / debug / se convierte en C: / _ bins / MyProject /