.NET Framework是否有将路径(例如"C:\whatever.txt"
)转换成档案URI(例如"file:///C:/whatever.txt"
)的方法?
System.Uri类的情况正好相反(从文件URI到绝对路径),但就我所知,没有任何东西可以转换为文件URI。
此外,这不是ASP.NET应用程序。
.NET Framework是否有将路径(例如"C:\whatever.txt"
)转换成档案URI(例如"file:///C:/whatever.txt"
)的方法?
System.Uri类的情况正好相反(从文件URI到绝对路径),但就我所知,没有任何东西可以转换为文件URI。
此外,这不是ASP.NET应用程序。
8条答案
按热度按时间ckx4rj1h1#
System.Uri
构造函数能够解析完整的文件路径,并将其转换为URI样式的路径。rslzwgfq2#
似乎没有人意识到的是,没有一个
System.Uri
构造函数能正确处理某些带有百分号的路径。这将得到
"file:///C:/Q.txt"
,而不是"file:///C:/%2551.txt"
。dontEscape参数的值没有任何区别,指定UriKind也会得到相同的结果。尝试使用UriBuilder也没有帮助:
这也会返回
"file:///C:/Q.txt"
。据我所知,这个框架实际上缺乏任何正确地做到这一点的方法。
我们可以尝试用正斜杠替换反斜杠,并将路径传递给
Uri.EscapeUriString
-即一开始这似乎是可行的,但是如果你给予它
C:\a b.txt
路径,那么你最终得到的是file:///C:/a%2520b.txt
而不是file:///C:/a%20b.txt
--不知何故,它决定了 * 一些 * 序列应该被解码,而其他的不应该。然而,这未能考虑诸如\\remote\share\foo.txt
的UNC路径-在Windows上似乎普遍接受的是将它们转换成file://remote/share/foo.txt
形式的伪url,所以我们也应该考虑到这点。EscapeUriString
还有一个问题,它不能转义'#'
字符。在这一点上,我们似乎别无选择,只能从头开始创建自己的方法。因此,我的建议是:这有意留下+和:未编码,因为这似乎是它通常在Windows上做的。它也只编码latin 1,因为Internet Explorer不能理解文件url中的unicode字符,如果他们被编码。
wwodge7n3#
上述解决方案在Linux上不起作用。
使用. NET Core时,尝试执行
new Uri("/home/foo/README.md")
会导致异常:您需要向CLR提供一些关于您拥有的URL类型的提示。
这是可行的:
...并且
fileUri.ToString()
返回的字符串为"file:///home/foo/README.md"
这也适用于Windows。
new Uri(new Uri("file://"), @"C:\Users\foo\README.md").ToString()
...发射
"file:///C:/Users/foo/README.md"
bjg7j2ky4#
VB.NET:
不同输出:
一个内衬:
输出:
file:///D:/Development/~AppFolder/Att/1.gif
qni6mghb5#
至少在.NET 4.5+中,您还可以:
wb1gzix06#
UrlCreateFromPath来拯救我们!嗯,不完全是,因为它不支持扩展和UNC路径格式,但这并不难克服:
如果路径以特殊前缀开头,则会将其删除,虽然文档中没有提到,但即使缓冲区较小,函数也会输出URL的长度,因此我首先获取长度,然后分配缓冲区。
我有一个非常有趣的观察结果:虽然“\device\path”被正确地转换为“file://device/path”,但具体来说,“\localhost\path”只被转换为“file:///path”。
WinApi函数成功地对特殊字符进行了编码,但不像 Uri 构造函数那样对Unicode特定字符进行编码。在这种情况下,AbsoluteUri 包含正确编码的URL,而 OriginalString 可用于保留Unicode字符。
u1ehiz5o7#
不幸的是,@poizan42答案没有考虑到我们生活在Unicode世界中的事实,而且根据RFC 3986,它的限制性太强。可接受的答案@pierre-arnaud和@jaredpar依赖于System.Uri构造函数,该构造函数必须处理太多的Uri组件,以便能够管理文件名的可变性,并且它在百分比字符和其他情况下失败得很差。其他的答案都是简单化的或者根本没用的。最好的答案应该是@is4,但是在发布了这篇文章的第一个版本之后,我在我为我自己编写的测试用例中一起测试了它,它在许多Unicode字符上都失败了。
在我的例子中,我开始研究@poizan42代码和各种各样的答案,评论什么是工作的,什么是不工作的,所以我采取了一个稍微不同的方法。
首先我认为输入字符串是一个有效的文件路径,因此我在测试中使用所有有效的unicode字符和代理项对以编程方式创建了path。()似乎至少在Windows中返回了正确的集合。然后,我将这些路径传递给了一个方法,该方法是我按照ABNF路径规则实现的,您可以在https://www.ietf.org/rfc/rfc3986.txt的第22页找到该规则。
我将它的结果与UriBuilder生成的结果进行了比较,这是最终的修复结果:
这是完全未经优化的,并执行三个替换,所以随时可以将其转换为Span或StringBuilder。
sqxo8psd8#
解决方法很简单,只需使用Uri().ToString()方法,然后对空格(如果有的话)进行百分比编码。
正确返回 * 文件:///C:/my%20示例.txt*