将文件名转换为 file:// URL

Posted

技术标签:

【中文标题】将文件名转换为 file:// URL【英文标题】:Convert a filename to a file:// URL 【发布时间】:2012-07-26 02:42:26 【问题描述】:

在 WeasyPrint 的公共 API 中,我接受 html 输入的文件名(以及其他类型)。任何与内置 open() 一起使用的文件名都应该可以使用,但我需要将其转换为 file:// 方案中的 URL,稍后将传递给 urllib.urlopen()

(内部的一切都是 URL 形式。我需要有一个文档的“基本 URL”,以便使用 urlparse.urljoin() 解析相对 URL 引用。)

urllib.pathname2url 是一个开始:

将路径名路径从路径的本地语法转换为 URL 的路径组件中使用的形式。 这不会产生完整的 URL。返回值已经使用 quote() 函数引用。

重点是我的,但我确实需要一个完整的 URL。到目前为止,这似乎有效:

def path2url(path):
    """Return file:// URL from a filename."""
    path = os.path.abspath(path)
    if isinstance(path, unicode):
        path = path.encode('utf8')
    return 'file:' + urlparse.pathname2url(path)

RFC 3987 (IRI) 似乎推荐使用 UTF-8。但在这种情况下(URL 最终是用于 urllib)也许我应该使用sys.getfilesystemencoding()?

但是,基于the literature,我应该不只是在file: 前面加上file:// ...除非我不应该:在Windows 上,nturl2path.pathname2url() 的结果已经以三个斜杠开头。

所以问题是:有没有更好的方法来做到这一点并使其跨平台?

【问题讨论】:

您不能只检查url[0:2] == '///' 之类的内容,如果为假,则添加两个额外的斜线吗? 约阿希姆,也许这行得通。我只是不知道要遵循什么规则来避免令人惊讶的极端情况。 嘿,您的示例代码使用了urlparse.pathname2url,它不存在。你的意思是urllib.pathname2url 【参考方案1】:

感谢上述@danodonovan 的评论。

对于 Python3,以下代码将起作用:

from urllib.parse import urljoin
from urllib.request import pathname2url

def path2url(path):
    return urljoin('file:', pathname2url(path))

【讨论】:

【参考方案2】:

为了完整起见,在 Python 3.4+ 中,您应该这样做:

import pathlib

pathlib.Path(absolute_path_string).as_uri()

【讨论】:

这个模块也在 PyPI 上(对于其他 Python 版本)pypi.python.org/pypi/pathlib pathlib2 现在应该用于其他 Python 版本 as_uri() 不适用于相对文件名(存在仅将部分文件名转换为(部分)URL 的用例【参考方案3】:

我不确定文档是否足够严格以保证这一点,但我认为这在实践中有效:

import urlparse, urllib

def path2url(path):
    return urlparse.urljoin(
      'file:', urllib.pathname2url(path))

【讨论】:

在 Linux、Windows 和 OS X 上测试过,并且在这三者上都可以正常工作。 而在 py3k 中,这变成了 import urlib.parse as urlparseimport urlib.request as urllib 您应该在这里致电os.path.abspath(path) 如果您使用 six 库来确保 Python 2 和 3 的可移植性:return six.moves.urllib_parse.urljoin( "file://", six.moves.urllib.request.pathname2url(path)) 这会产生看起来像file:///C:/foo%20bar/spam/eggs" 的url 不应该是file:///C%3A/foo%20bar/spam/eggs",冒号变成%3A【参考方案4】:

以下内容对您有用吗?

from urlparse import urlparse, urlunparse

urlunparse(urlparse('yourURL')._replace(scheme='file'))

【讨论】:

这个想法很有趣,但我不知道这是否足够。特别是,` in Windows filenames is supposed to become /. Still on Windows, The C in C:\foo\bar.html` 被解析为一个方案,然后被替换。预期输出为file:///C:/foo/bar.html

以上是关于将文件名转换为 file:// URL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET 中将文件路径转换为 ​​URL

在url中如果访问本地文件将使用file协议?

将 url 转换为 NSData

Java 笔记

如何将url转换为文件名?

将 HTML5 Canvas 转换为要上传的文件?