O .NET Framework possui métodos para converter um caminho (por exemplo "C:\whatever.txt"
) em um URI de arquivo (por exemplo,"file:///C:/whatever.txt"
)?
A classe System.Uri tem o inverso (de um URI de arquivo para o caminho absoluto), mas nada que eu possa encontrar para converter em um URI de arquivo.
Além disso, este não é um aplicativo ASP.NET.
var path = new Uri("file:///C:/whatever.txt").LocalPath;
transforma um Uri de volta em um caminho de arquivo local também para quem precisa disso.new Uri(@"C:\%51.txt").AbsoluteUri
dá-lhe em"file:///C:/Q.txt"
vez de"file:///C:/%2551.txt"
O que ninguém parece perceber é que nenhum dos
System.Uri
construtores manipula corretamente certos caminhos com sinais de porcentagem neles.Isso dá a você, em
"file:///C:/Q.txt"
vez de"file:///C:/%2551.txt"
.Nenhum dos valores do argumento dontEscape descontinuado faz qualquer diferença e a especificação do UriKind também fornece o mesmo resultado. Tentar com o UriBuilder também não ajuda:
Isso retorna
"file:///C:/Q.txt"
também.Tanto quanto posso dizer, o framework realmente não tem nenhuma maneira de fazer isso corretamente.
Podemos tentar isso substituindo as barras invertidas por barras invertidas e alimentando o caminho para
Uri.EscapeUriString
- ieIsso parece funcionar no começo, mas se você der o caminho
C:\a b.txt
, você termina com, emfile:///C:/a%2520b.txt
vez defile:///C:/a%20b.txt
- de alguma forma, decide que algumas seqüências devem ser decodificadas, mas não outras. Agora podemos apenas prefixar a"file:///"
nós mesmos, no entanto, isso não leva\\remote\share\foo.txt
em consideração os caminhos UNC - o que parece ser geralmente aceito no Windows é transformá-los em pseudo-urls do formuláriofile://remote/share/foo.txt
, por isso devemos levar isso em consideração também.EscapeUriString
também tem o problema de não escapar do'#'
personagem. Parece que, nesse ponto, não temos outra escolha a não ser fazer nosso próprio método a partir do zero. Então é isso que eu sugiro:Isso deixa intencionalmente + e: sem codificação, pois parece que é assim que geralmente é feito no Windows. Ele também codifica latin1, pois o Internet Explorer não pode entender caracteres unicode em URLs de arquivo se eles estiverem codificados.
fonte
As soluções acima não funcionam no Linux.
Usando o .NET Core, a tentativa de executar
new Uri("/home/foo/README.md")
resultados em uma exceção:Você precisa fornecer ao CLR algumas dicas sobre que tipo de URL você possui.
Isso funciona:
... e a string retornada por
fileUri.ToString()
é"file:///home/foo/README.md"
Isso funciona no Windows também.
new Uri(new Uri("file://"), @"C:\Users\foo\README.md").ToString()
... emite
"file:///C:/Users/foo/README.md"
fonte
new Uri("/path/to/file", UriKind.Absolute);
VB.NET:
Saídas diferentes:
Um forro:
fonte
AbsoluteUri
está correto porque também codifica espaços para% 20.Pelo menos no .NET 4.5+, você também pode:
fonte
UriFormatException
um dia?new Uri(@"C:\%51.txt",UriKind.Absolute).AbsoluteUri
retorna em"file:///C:/Q.txt"
vez de"file:///C:/%2551.txt"
UrlCreateFromPath para o resgate! Bem, não inteiramente, pois ele não suporta os formatos de caminho estendido e UNC, mas isso não é tão difícil de superar:
Caso o caminho comece com um prefixo especial, ele será removido. Embora a documentação não mencione isso, a função gera o tamanho da URL, mesmo que o buffer seja menor, então eu primeiro obtenho o tamanho e aloco o buffer.
Alguns muito observação interessante que tive é que, enquanto "\\ device \ path" é corretamente transformado em "file: // device / path", especificamente "\\ localhost \ path" é transformado em apenas "file: /// path" .
A função WinApi conseguiu codificar caracteres especiais, mas deixa os caracteres específicos do Unicode não codificados, ao contrário do construtor Uri . Nesse caso, AbsoluteUri contém a URL codificada corretamente, enquanto OriginalString pode ser usado para reter os caracteres Unicode.
fonte
A solução alternativa é simples. Basta usar o método Uri (). ToString () e espaços em branco com codificação percentual, se houver, posteriormente.
retorna corretamente o arquivo: /// C: / my% 20example ㄓ .txt
fonte