@ Joe, estúpido tiene razón! Además, debo señalar que la función equivalente funciona bien en Node.JS ... Sacudiendo mi cabeza en Microsoft ...
NH.
2
@zwcloud Para .NET Core / Standard, Path.Combine()es principalmente para la compatibilidad con versiones anteriores (con el comportamiento existente). Sería mejor usar Path.Join(): "A diferencia del método Combinar, el método Join no intenta enraizar la ruta devuelta. (Es decir, si path2 es una ruta absoluta, el método Join no descarta path1 y devuelve path2 como Combine método lo hace.) "
Stajs
Respuestas:
205
Esta es una especie de pregunta filosófica (que tal vez solo Microsoft realmente pueda responder), ya que está haciendo exactamente lo que dice la documentación.
No sé cuál es la razón. Supongo que la solución es quitar (o Recortar) DirectorySeparatorChar desde el comienzo de la segunda ruta; tal vez escriba su propio método Combine que haga eso y luego llame a Path.Combine ().
Mirando el código desmontado (revise mi publicación), tiene razón en cierto sentido.
Gulzar Nazim
77
Supongo que funciona de esa manera para permitir un fácil acceso al algoritmo "directorio de trabajo actual".
BCS
Parece funcionar como hacer una secuencia cd (component)desde la línea de comandos. A mí me parece razonable.
Adrian Ratnapala
11
Utilizo este recorte para obtener el efecto deseado string strFilePath = Path.Combine (basePath, otherPath.TrimStart (new char [] {'\\', '/'}));
Matthew Lock
3
Path.Combine
Cambié
23
Este es el código desmontado de .NET Reflector para el método Path.Combine. Verifique la función IsPathRooted. Si la segunda ruta está enraizada (comienza con un DirectorySeparatorChar), devuelva la segunda ruta tal como está.
En mi opinión esto es un error. El problema es que hay dos tipos diferentes de rutas "absolutas". La ruta "d: \ mydir \ myfile.txt" es absoluta, la ruta "\ mydir \ myfile.txt" también se considera "absoluta" a pesar de que le falta la letra de la unidad. El comportamiento correcto, en mi opinión, sería anteponer la letra de la unidad de la primera ruta cuando la segunda ruta comienza con el separador de directorio (y no es una ruta UNC). Recomendaría escribir su propia función de envoltura auxiliar que tiene el comportamiento que desea si lo necesita.
Coincide con las especificaciones, pero tampoco es lo que esperaba.
dthrasher
@Jake Eso no es evitar una corrección de errores; son varias personas que piensan mucho sobre cómo hacer algo, y luego se adhieren a lo que acuerden. Además, tenga en cuenta la diferencia entre el marco .Net (una biblioteca que contiene Path.Combine) y el lenguaje C #.
Si una de las rutas especificadas es una cadena de longitud cero, este método devuelve la otra ruta. Si path2 contiene una ruta absoluta, este método devuelve path2.
Algunos aconsejan que los espacios de nombres deben colisionar, ... Fui con Pathyun poco y para evitar la colisión del espacio de nombres System.IO.Path.
Editar : se agregaron verificaciones de parámetros nulos
Esto significa que cuando une una ruta con una barra inclinada anterior, en realidad está uniendo una base a otra, en cuyo caso la segunda tiene prioridad.
En realidad, esto tiene sentido, de alguna manera, considerando cómo se tratan las rutas (relativas) generalmente:
stringGetFullPath(string path){string baseDir =@"C:\Users\Foo.Bar";returnPath.Combine(baseDir, path);}// Get full path for RELATIVE file pathGetFullPath("file.txt");// = C:\Users\Foo.Bar\file.txt// Get full path for ROOTED file pathGetFullPath(@"C:\Temp\file.txt");// = C:\Temp\file.txt
La verdadera pregunta es: ¿por qué los caminos, que comienzan con "\", se consideran "enraizados"? Esto también era nuevo para mí, pero funciona de esa manera en Windows :
Esto significa "el directorio raíz de la unidad actual". En su ejemplo, significa la carpeta "prueba" en el directorio raíz de la unidad actual. Entonces, esto puede ser igual a "c: \ test".
Como mencionó Ryan, está haciendo exactamente lo que dice la documentación.
Desde tiempos de DOS, se distinguen el disco actual y la ruta actual.
\es la ruta raíz, pero para el DISCO ACTUAL.
Para cada " disco " hay una " ruta actual " separada . Si cambia el disco usando cd D:, no cambia la ruta actual aD:\ , sino a: "D: \ lo que sea \ fue \ la \ última \ ruta \ accedido \ en \ este \ disco" ...
Entonces, en Windows, un literal @"\x"significa: "CURRENTDISK: \ x". Por lo tanto, Path.Combine(@"C:\x", @"\y")tiene como segundo parámetro una ruta raíz, no un pariente, aunque no en un disco conocido ... Y dado que no se sabe cuál podría ser el «disco actual», Python regresa "\\y".
Path.Combine()
es principalmente para la compatibilidad con versiones anteriores (con el comportamiento existente). Sería mejor usarPath.Join()
: "A diferencia del método Combinar, el método Join no intenta enraizar la ruta devuelta. (Es decir, si path2 es una ruta absoluta, el método Join no descarta path1 y devuelve path2 como Combine método lo hace.) "Respuestas:
Esta es una especie de pregunta filosófica (que tal vez solo Microsoft realmente pueda responder), ya que está haciendo exactamente lo que dice la documentación.
System.IO.Path.Combine
"Si path2 contiene una ruta absoluta, este método devuelve path2".
Aquí está el método de combinación real de la fuente .NET. Puede ver que llama a CombineNoChecks , que luego llama a IsPathRooted en path2 y devuelve esa ruta si es así:
No sé cuál es la razón. Supongo que la solución es quitar (o Recortar) DirectorySeparatorChar desde el comienzo de la segunda ruta; tal vez escriba su propio método Combine que haga eso y luego llame a Path.Combine ().
fuente
cd (component)
desde la línea de comandos. A mí me parece razonable.Path.Combine
Este es el código desmontado de .NET Reflector para el método Path.Combine. Verifique la función IsPathRooted. Si la segunda ruta está enraizada (comienza con un DirectorySeparatorChar), devuelva la segunda ruta tal como está.
fuente
Quería resolver este problema:
Por supuesto, todas las rutas 1-9 deben contener una cadena equivalente al final. Aquí está el método PathCombine que se me ocurrió:
También creo que es bastante molesto que este manejo de cadenas se haga manualmente, y me interesaría la razón detrás de esto.
fuente
En mi opinión esto es un error. El problema es que hay dos tipos diferentes de rutas "absolutas". La ruta "d: \ mydir \ myfile.txt" es absoluta, la ruta "\ mydir \ myfile.txt" también se considera "absoluta" a pesar de que le falta la letra de la unidad. El comportamiento correcto, en mi opinión, sería anteponer la letra de la unidad de la primera ruta cuando la segunda ruta comienza con el separador de directorio (y no es una ruta UNC). Recomendaría escribir su propia función de envoltura auxiliar que tiene el comportamiento que desea si lo necesita.
fuente
Path.Combine
) y el lenguaje C #.De MSDN :
En su ejemplo, path2 es absoluto.
fuente
Siguiendo el consejo de Christian Graus en su blog "Cosas que odio sobre Microsoft" titulado " Path.Combine es esencialmente inútil ", aquí está mi solución:
Algunos aconsejan que los espacios de nombres deben colisionar, ... Fui con
Pathy
un poco y para evitar la colisión del espacio de nombresSystem.IO.Path
.Editar : se agregaron verificaciones de parámetros nulos
fuente
Este código debería hacer el truco:
fuente
Sin conocer los detalles reales, supongo que hace un intento de unirse como si pudiera unirse a URI relativos. Por ejemplo:
Esto significa que cuando une una ruta con una barra inclinada anterior, en realidad está uniendo una base a otra, en cuyo caso la segunda tiene prioridad.
fuente
Razón:
Su segunda URL se considera una ruta absoluta, la
Combine
método solo devolverá la última ruta si la última ruta es absoluta.Solución: simplemente elimine la barra diagonal inicial
/
de su segunda ruta (/SecondPath
aSecondPath
). Entonces funciona como lo exceptuaste.fuente
En realidad, esto tiene sentido, de alguna manera, considerando cómo se tratan las rutas (relativas) generalmente:
La verdadera pregunta es: ¿por qué los caminos, que comienzan con
"\"
, se consideran "enraizados"? Esto también era nuevo para mí, pero funciona de esa manera en Windows :fuente
Si desea combinar ambas rutas sin perder ninguna ruta, puede usar esto:
O con variables:
Ambos casos devuelven "C: \ test \ test".
Primero, evalúo si Path2 comienza con / y si es cierto, devuelvo Path2 sin el primer carácter. De lo contrario, devuelva el Path2 completo.
fuente
== @"\"
cheque por unaPath.IsRooted()
llamada, ya"\"
que no es el único personaje a tener en cuenta.Estos dos métodos deberían salvarlo de unir accidentalmente dos cadenas que tienen el delimitador en ellas.
fuente
Esto significa "el directorio raíz de la unidad actual". En su ejemplo, significa la carpeta "prueba" en el directorio raíz de la unidad actual. Entonces, esto puede ser igual a "c: \ test".
fuente
Elimine la barra diagonal inicial ('\') en el segundo parámetro (ruta2) de Path.Combine.
fuente
Utilicé la función de agregado para forzar la combinación de rutas de la siguiente manera:
fuente
Como mencionó Ryan, está haciendo exactamente lo que dice la documentación.
Desde tiempos de DOS, se distinguen el disco actual y la ruta actual.
\
es la ruta raíz, pero para el DISCO ACTUAL.Para cada " disco " hay una " ruta actual " separada . Si cambia el disco usando
cd D:
, no cambia la ruta actual aD:\
, sino a: "D: \ lo que sea \ fue \ la \ última \ ruta \ accedido \ en \ este \ disco" ...Entonces, en Windows, un literal
@"\x"
significa: "CURRENTDISK: \ x". Por lo tanto,Path.Combine(@"C:\x", @"\y")
tiene como segundo parámetro una ruta raíz, no un pariente, aunque no en un disco conocido ... Y dado que no se sabe cuál podría ser el «disco actual», Python regresa"\\y"
.fuente