net getfilename combine asp c# .net path

c# - getfilename - ¿Cómo garantizar que haya un separador de directorios posterior en las rutas?



relative path c# (4)

Tengo un problema con AppDomain.CurrentDomain.BaseDirectory .

A veces el camino termina con ''/' y otras veces no. No puedo encontrar una razón para esto.

Estaría bien si estuviera usando Path.Combine pero quiero hacer Directory.GetParent y arroja resultados diferentes.

¿Has encontrado este problema?

¿Puedo hacer las cosas de manera diferente para obtener el directorio principal de la aplicación?

Mi hack actual es:

var baseDir = AppDomain.CurrentDomain.BaseDirectory; if (!baseDir.EndsWith("//")) baseDir += "//";


A menudo uso

path = Path.Combine(path, "x"); path = path.Substring(0, path.Length - 1);

O, si lo necesitaba más de una o dos veces en el mismo proyecto, probablemente usaría una función auxiliar como esta:

string EnsureTerminatingDirectorySeparator(string path) { if (path == null) throw new ArgumentNullException("path"); int length = path.Length; if (length == 0) return "." + Path.DirectorySeparatorChar; char lastChar = path[length - 1]; if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar) return path; int lastSep = path.LastIndexOfAny(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); if (lastSep >= 0) return path + path[lastSep]; else return path + Path.DirectorySeparatorChar; }


Es así, solo mantén tu truco.

En Win32 simple hay una función auxiliar PathAddBackslash para eso. Simplemente sea coherente con el separador de directorios: marque Path.DirectorySeparatorChar y Path.AltDirectorySeparatorChar lugar de hard-code / .

Algo como esto (tenga en cuenta que no hay una comprobación de error grave):

string PathAddBackslash(string path) { // They''re always one character but EndsWith is shorter than // array style access to last path character. Change this // if performance are a (measured) issue. string separator1 = Path.DirectorySeparatorChar.ToString(); string separator2 = Path.AltDirectorySeparatorChar.ToString(); // Trailing white spaces are always ignored but folders may have // leading spaces. It''s unusual but it may happen. If it''s an issue // then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out. path = path.TrimEnd(); // Argument is always a directory name then if there is one // of allowed separators then I have nothing to do. if (path.EndsWith(separator1) || path.EndsWith(separator2)) return path; // If there is the "alt" separator then I add a trailing one. // Note that URI format (file://drive:/path/filename.ext) is // not supported in most .NET I/O functions then we don''t support it // here too. If you have to then simply revert this check: // if (path.Contains(separator1)) // return path + separator1; // // return path + separator2; if (path.Contains(separator2)) return path + separator2; // If there is not an "alt" separator I add a "normal" one. // It means path may be with normal one or it has not any separator // (for example if it''s just a directory name). In this case I // default to normal as users expect. return path + separator1; }

¿Por qué tanto código? Principal porque si el usuario ingresa /windows/system32 no quiere obtener /windows/system32/ pero /windows/system32/ , el diablo está en los detalles ...

Para poner todo junto en una forma mejor auto-explicativa:

string PathAddBackslash(string path) { if (path == null) throw new ArgumentNullException(nameof(path)); path = path.TrimEnd(); if (PathEndsWithDirectorySeparator()) return path; return path + GetDirectorySeparatorUsedInPath(); bool PathEndsWithDirectorySeparator() { if (path.Length == 0) return false; char lastChar = path[path.Length - 1]; return lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar; } char GetDirectorySeparatorUsedInPath() { if (path.Contains(Path.AltDirectorySeparatorChar)) return Path.AltDirectorySeparatorChar; return Path.DirectorySeparatorChar; } }

El file:// formato URI file:// no se maneja aunque parezca así. Lo correcto es volver a hacer lo que hacen las otras funciones de E / S .NET: no maneje este formato (y posiblemente genere una excepción).

Como alternativa, siempre puedes importar la función Win32:

[DllImport("shlwapi.dll", EntryPoint = "PathAddBackslashW", SetLastError = True, CharSet = CharSet.Unicode)] static extern IntPtr PathAddBackslash( [MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);


Para obtener soporte multiplataforma, puede usar este fragmento:

using System.IO; // Your input string. string baseDir = AppDomain.CurrentDomain.BaseDirectory; // Get the absolut path from it (in case ones input is a relative path). string fullPath = Path.GetFullPath(baseDir); // Check for ending slashes, remove them (if any) // and add a cross platform slash at the end. string result = fullPath .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;

Como un método:

private static string GetFullPathWithEndingSlashes(string input) { string fullPath = Path.GetFullPath(input); return fullPath .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; }

O como un método de extensión:

public static string GetFullPathWithEndingSlashes(this string input) { return Path.GetFullPath(input) .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar; }


Puede garantizar fácilmente el comportamiento que desea utilizando TrimEnd :

var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd(''//') + "//";

Para ser eficiente de manera óptima (evitando asignaciones adicionales), verifique que la cadena no termine con un / antes de realizar cambios, ya que no siempre será necesario:

var baseDir = AppDomain.CurrentDomain.BaseDirectory; if (!baseDir.EndsWith("//")) { baseDir += "//"; }