Hay una parte en mis aplicaciones que muestra la ruta del archivo cargado por el usuario a través de OpenFileDialog. Está ocupando demasiado espacio para mostrar la ruta completa, pero no quiero mostrar solo el nombre del archivo, ya que puede ser ambiguo. Así que preferiría mostrar la ruta del archivo en relación con el directorio ensamblado / exe.
Por ejemplo, el ensamblaje reside en C:\Program Files\Dummy Folder\MyProgram
y el archivo en C:\Program Files\Dummy Folder\MyProgram\Data\datafile1.dat
ese momento me gustaría que se muestre .\Data\datafile1.dat
. Si el archivo está dentro C:\Program Files\Dummy Folder\datafile1.dat
, entonces me gustaría ..\datafile1.dat
. Pero si el archivo está en el directorio raíz o 1 directorio debajo de la raíz, entonces muestre la ruta completa.
¿Qué solución recomendarías? Regex?
Básicamente quiero mostrar información útil de la ruta del archivo sin ocupar demasiado espacio en la pantalla.
EDITAR: Solo para aclarar un poco más. El propósito de esta solución es ayudar al usuario o a mí mismo a saber qué archivo cargué por última vez y aproximadamente de qué directorio provenía. Estoy usando un cuadro de texto de solo lectura para mostrar la ruta. La mayoría de las veces, la ruta del archivo es mucho más larga que el espacio de visualización del cuadro de texto. Se supone que la ruta es informativa pero no lo suficientemente importante como para ocupar más espacio en la pantalla.
El comentario de Alex Brault fue bueno, al igual que Jonathan Leffler. La función Win32 proporcionada por DavidK solo ayuda con parte del problema, no con todo, pero gracias de todos modos. En cuanto a la solución de James Newton-King, lo intentaré más tarde cuando esté libre.
Respuestas:
.NET Core 2.0 tiene
Path.GetRelativePath
, de lo contrario, usar esto.fuente
return relativeUri.ToString().Replace('/',Path.DirectorySeparatorChar);
c:\test
yc:\test\abc.txt
devuelve lotest\abc.txt
que no es relativo en mi opinión. Yo esperaría soloabc.txt
Un poco tarde para la pregunta, pero también necesitaba esta función también. Estoy de acuerdo con DavidK en que, dado que hay una función de API incorporada que proporciona esto, debe usarla. Aquí hay un contenedor administrado para ello:
fuente
Respuesta de .NET Core 2.0
.NET Core 2.0 tiene Path.GetRelativePath que se puede usar así:
En el ejemplo anterior, la
relativePath
variable es igual aData\datafile1.dat
.Respuesta alternativa .NET
La solución de @ Dave no funciona cuando las rutas de los archivos no terminan con un carácter de barra diagonal (
/
) que puede suceder si la ruta es una ruta de directorio. Mi solución soluciona ese problema y también utiliza laUri.UriSchemeFile
constante en lugar de la codificación rígida"FILE"
.Respuesta de interoperabilidad de Windows
Hay una API de Windows llamada PathRelativePathToA que se puede usar para encontrar una ruta relativa. Tenga en cuenta que las rutas de archivo o directorio que pasa a la función deben existir para que funcione.
fuente
AltDirectorySeparatorChar
es una posibilidad, ¿no deberíasAppendDirectorySeparatorChar
comprobarlo también?Hay una función Win32 (C ++) en shlwapi.dll que hace exactamente lo que desea:
PathRelativePathTo()
Sin embargo, no conozco ninguna forma de acceder a esto desde .NET que no sea P / Invocarlo.
fuente
shlwapi.dll
ahora están en desuso msdn.microsoft.com/en-us/library/windows/desktop/…"These functions are available through Windows XP Service Pack 2 (SP2) and Windows Server 2003. They might be altered or unavailable in subsequent versions of Windows."
Si está utilizando .NET Core 2.0,
Path.GetRelativePath()
está disponible proporcionando esta funcionalidad específica:De lo contrario, para .NET full framework (a partir de v4.7) recomendamos usar una de las otras respuestas sugeridas.
fuente
He usado esto en el pasado.
fuente
Como señala Alex Brault, especialmente en Windows, la ruta absoluta (con letra de unidad y todo) es inequívoca y, a menudo, mejor.
¿No debería su OpenFileDialog utilizar una estructura de árbol de navegador normal?
Para establecer alguna nomenclatura, RefDir es el directorio relativo al que desea especificar la ruta; la AbsName es el nombre de ruta absoluta que desea asignar; y RelPath es la ruta relativa resultante.
Tome la primera de estas opciones que coincida:
Para ilustrar la última regla (que es, por supuesto, con mucho la más compleja), comience con:
Luego
Mientras escribía, DavidK produjo una respuesta que sugiere que no eres el primero en necesitar esta función y que hay una función estándar para hacer este trabajo. Úsalo. Pero tampoco hay daño en poder pensar desde los primeros principios.
Excepto que los sistemas Unix no admiten letras de unidad (por lo que todo está siempre ubicado en el mismo directorio raíz y, por lo tanto, la primera viñeta es irrelevante), la misma técnica podría usarse en Unix.
fuente
Es un largo camino, pero la clase System.Uri tiene un método llamado MakeRelativeUri. Tal vez podrías usar eso. Es una lástima que System.IO.Path no tenga esto.
fuente
Como se señaló anteriormente .NET Core 2.x tiene implementación de
Path.GetRelativePath
.El siguiente código está adaptado de las fuentes y funciona bien con .NET 4.7.1 Framework.
fuente
Estoy usando esto:
fuente
Utilizar:
fuente
path.Replace(rootPath.TrimEnd('\\') + "\\", "")
.Si está seguro de que su ruta absoluta 2 siempre es relativa a la ruta absoluta, simplemente elimine los primeros N caracteres de la ruta2, donde N es la longitud de la ruta1.
fuente
Desea usar el
CommonPath
método de estaRelativePath
clase. Una vez que tenga la ruta común, simplemente quítela de la ruta que desea mostrar.fuente
Dividiría ambas rutas en el nivel de directorio. A partir de ahí, encuentre el punto de divergencia y vuelva a la carpeta de ensamblaje, anteponiendo un '../' cada vez que pase un directorio.
Sin embargo, tenga en cuenta que una ruta absoluta funciona en todas partes y generalmente es más fácil de leer que una ruta relativa. Yo personalmente no le mostraría a un usuario una ruta relativa a menos que fuera absolutamente necesario.
fuente
Si sabe que toPath está contenido en fromPath, puede mantenerlo simple. Dejaré de lado las afirmaciones por brevedad.
fuente
La función que usa URI devolvió una ruta "casi" relativa. Incluyó el directorio que contiene directamente el archivo que ruta relativa quería obtener.
Hace algún tiempo escribí una función simple que devuelve la ruta relativa de la carpeta o archivo, e incluso si está en otra unidad, también incluye la letra de la unidad.
Por favor echa un vistazo:
fuente
Si tiene un cuadro de texto de solo lectura, ¿no podría no convertirlo en una etiqueta y establecer AutoEllipsis = true?
alternativamente, hay publicaciones con código para generar la autoelipsis usted mismo: (esto lo hace para una cuadrícula, en su lugar, necesitaría pasar el ancho del cuadro de texto. No es del todo correcto, ya que corta un poco más de lo necesario , y no he podido encontrar dónde el cálculo es incorrecto. Sería bastante fácil modificarlo para eliminar la primera parte del directorio en lugar de la última si lo desea.
fuente
fuente
Esto debería funcionar:
fuente
Manera con Uri no funcionó en sistemas linux / macOS. La ruta '/ var / www / root' no se puede convertir a Uri. De manera más universal, hazlo todo con las manos.
PD: uso "/" como valor predeterminado de separador en lugar de Path.DirectorySeparatorChar, porque el resultado de este método se utiliza como uri en mi aplicación.
fuente
Aquí está el mío:
fuente
Juega con algo como:
Y probarlo
fuente
En
ASP.NET Core 2
, si desea la ruta relativa abin\Debug\netcoreapp2.2
usted, puede usar la siguiente combinación:fuente