¿Tiene .NET Framework algún método para convertir una ruta (por ejemplo "C:\whatever.txt"
) en un URI de archivo (por ejemplo "file:///C:/whatever.txt"
)?
La clase System.Uri tiene el reverso (de un URI de archivo a una ruta absoluta), pero nada en lo que puedo encontrar para convertir a un URI de archivo.
Además, esta no es una aplicación ASP.NET.
var path = new Uri("file:///C:/whatever.txt").LocalPath;
convierte un Uri de nuevo en una ruta de archivo local también para cualquiera que lo necesite.new Uri(@"C:\%51.txt").AbsoluteUri
te da en"file:///C:/Q.txt"
lugar de"file:///C:/%2551.txt"
Lo que nadie parece darse cuenta es que ninguno de los
System.Uri
constructores maneja correctamente ciertas rutas con signos de porcentaje en ellas.Esto te da en
"file:///C:/Q.txt"
lugar de"file:///C:/%2551.txt"
.Ninguno de los valores del argumento dontEscape en desuso hace ninguna diferencia, y al especificar UriKind también se obtiene el mismo resultado. Intentar con UriBuilder tampoco ayuda:
Esto también regresa
"file:///C:/Q.txt"
.Por lo que puedo decir, el marco realmente carece de cualquier forma de hacer esto correctamente.
Podemos intentarlo reemplazando las barras diagonales inversas con barras diagonales hacia adelante y alimentando el camino a
Uri.EscapeUriString
, es decirEsto parece funcionar al principio, pero si le das el camino,
C:\a b.txt
entonces terminas enfile:///C:/a%2520b.txt
lugar defile:///C:/a%20b.txt
: de alguna manera, decide que algunas secuencias deben decodificarse pero no otras. Ahora podríamos prefijarnos a"file:///"
nosotros mismos, sin embargo, esto no toma\\remote\share\foo.txt
en cuenta las rutas UNC , lo que parece ser generalmente aceptado en Windows es convertirlas en pseudo-urls de la formafile://remote/share/foo.txt
, por lo que también debemos tener eso en cuenta.EscapeUriString
También tiene el problema de que no escapa al'#'
personaje. En este punto, parecería que no tenemos otra opción que hacer nuestro propio método desde cero. Entonces esto es lo que sugiero:Esto deja intencionalmente + y: sin codificar, ya que parece ser la forma en que generalmente se hace en Windows. También solo codifica latin1 ya que Internet Explorer no puede entender los caracteres unicode en las URL de los archivos si están codificados.
fuente
Las soluciones anteriores no funcionan en Linux.
Usando .NET Core, intentando ejecutar
new Uri("/home/foo/README.md")
resultados en una excepción:Debe dar al CLR algunas pistas sobre qué tipo de URL tiene.
Esto funciona:
... y la cadena devuelta por
fileUri.ToString()
es"file:///home/foo/README.md"
Esto también funciona en Windows.
new Uri(new Uri("file://"), @"C:\Users\foo\README.md").ToString()
... emite
"file:///C:/Users/foo/README.md"
fuente
new Uri("/path/to/file", UriKind.Absolute);
VB.NET:
Diferentes salidas:
Un trazador de líneas:
fuente
AbsoluteUri
es correcto porque codifica también espacios a% 20.Al menos en .NET 4.5+ también puedes hacer:
fuente
UriFormatException
día?new Uri(@"C:\%51.txt",UriKind.Absolute).AbsoluteUri
regresa en"file:///C:/Q.txt"
lugar de"file:///C:/%2551.txt"
UrlCreateFromPath al rescate! Bueno, no del todo, ya que no admite formatos de ruta extendidos y UNC, pero eso no es tan difícil de superar:
En caso de que la ruta comience con un prefijo especial, se elimina. Aunque la documentación no lo menciona, la función genera la longitud de la URL incluso si el búfer es más pequeño, por lo que primero obtengo la longitud y luego asigno el búfer.
Algunos muy observación interesante que tuve es que mientras "\\ device \ path" se transforma correctamente en "file: // device / path", específicamente "\\ localhost \ path" se transforma simplemente en "file: /// path" .
La función WinApi logró codificar caracteres especiales, pero deja los caracteres específicos de Unicode sin codificar, a diferencia del constructor Uri . En ese caso, AbsoluteUri contiene la URL codificada correctamente, mientras que OriginalString puede usarse para retener los caracteres Unicode.
fuente
La solución es simple. Simplemente use el método Uri (). ToString () y codifique con espacios en blanco, si corresponde, después.
devuelve correctamente el archivo: /// C: / my% 20example ㄓ .txt
fuente