检查路径在 Python 中是不是有效,而不在路径的目标处创建文件

Posted

技术标签:

【中文标题】检查路径在 Python 中是不是有效,而不在路径的目标处创建文件【英文标题】:Check whether a path is valid in Python without creating a file at the path's target检查路径在 Python 中是否有效,而不在路径的目标处创建文件 【发布时间】:2012-03-20 21:49:13 【问题描述】:

我有一个路径(包括目录和文件名)。 我需要测试文件名是否有效,例如如果文件系统允许我创建一个具有这样名称的文件。 文件名包含一些 unicode 字符

可以安全地假设路径的目录段是有效且可访问的(我试图让这个问题更普遍适用,但显然我太过分了)。

我非常不想逃避任何事情,除非我不得不

我会发布一些我正在处理的示例字符,但显然它们会被堆栈交换系统自动删除。无论如何,我想保留标准的 unicode 实体,例如 ö,并且只转义文件名中无效的内容。


这就是问题所在。 路径的目标可能已经存在(也可能不存在)一个文件。如果该文件存在,我需要保留该文件,如果不存在,则不要创建文件。

基本上,我想检查我是否可以写入路径而不实际打开写入路径(以及通常需要的自动文件创建/文件破坏)。

这样:

try:
    open(filename, 'w')
except OSError:
    # handle error here

from here

不可接受,因为它会覆盖我不想触摸的现有文件(如果存在),或者如果不存在则创建所述文件。

我知道我能做到:

if not os.access(filePath, os.W_OK):
    try:
        open(filePath, 'w').close()
        os.unlink(filePath)
    except OSError:
        # handle error here

但这会创建文件在filePath,然后我必须os.unlink

最后,它似乎要花费 6 或 7 行来做一些应该像 os.isvalidpath(filePath) 或类似的简单的事情。


顺便说一句,我需要它(至少)在 Windows 和 MacOS 上运行,所以我想避免特定于平台的东西。

``

【问题讨论】:

如果您想测试路径是否存在并且可以写入,那么只需创建和删除其他文件。给它一个唯一的名称(或尽可能唯一),以避免多用户/多线程问题。否则,您正在查看权限,这将使您直接陷入操作系统特定的混乱。 @Tony Hopkinson - 基本上我想检查我是否可以写入路径而不实际写入任何内容 如果你没有任何东西要写入文件,那你为什么需要知道你是否有能力呢? @FakeName - 你总是会在这里遇到微妙的竞争条件。在检查文件不存在但可以创建之间,然后创建文件,其他一些进程可以创建它,无论如何你都会破坏文件。当然,这是否是一个现实问题取决于您的使用情况...... 部分你可以用os.path.isabs(PATH)检查它,但这不包括相对路径:-(。 【参考方案1】:

tl;博士

调用下面定义的is_path_exists_or_creatable()函数。

严格来说是 Python 3。这就是我们滚动的方式。

两个问题的故事

“我如何测试路径名的有效性,以及对于有效路径名,这些路径的存在性或可写性”的问题?显然是两个独立的问题。两者都很有趣,而且都没有在这里得到真正令人满意的答案......或者,嗯,我可以grep的任何地方

vikki 的answer 可能是最接近的,但具有以下显着缺点:

不必要地打开(...然后无法可靠地关闭)文件句柄。 不必要地写入(...然后无法可靠地关闭或删除)0 字节文件。 忽略区分不可忽略的无效路径名和可忽略的文件系统问题的特定于操作系统的错误。不出所料,这在 Windows 下至关重要。 (见下文。) 忽略外部进程同时(重新)移动要测试的路径名的父目录导致的竞争条件。 (见下文。) 忽略此路径名导致的连接超时,该路径名驻留在陈旧、缓慢或其他暂时无法访问的文件系统上。这可能将面向公众的服务暴露给潜在的DoS 驱动的攻击。 (见下文。

我们会解决所有这些问题。

问题 #0:什么是路径名有效性?

在将我们脆弱的肉服扔进布满蟒蛇的痛苦沼泽之前,我们应该先定义一下“路径名有效性”的含义。究竟是什么定义了有效性?

“路径名有效性”是指路径名相对于当前系统的根文件系统句法正确性——无论是该路径还是父目录其物理存在。如果路径名符合根文件系统的所有语法要求,则路径名在此定义下的语法是正确的。

“根文件系统”是指:

在 POSIX 兼容系统上,文件系统挂载到根目录 (/)。 在 Windows 上,文件系统挂载到 %HOMEDRIVE%,即包含当前 Windows 安装的以冒号后缀的驱动器号(通常但不一定必须是 C:)。

反过来,“句法正确性”的含义取决于根文件系统的类型。对于ext4(以及大多数但不是所有POSIX兼容的)文件系统,路径名在语法上是正确的当且仅当该路径名:

不包含空字节(即 Python 中的 \x00)。 这是所有 POSIX 兼容文件系统的硬性要求。 不包含长度超过 255 个字节的路径组件(例如,Python 中的 'a'*256)。路径组件是不包含/ 字符的路径名的最长子字符串(例如,路径名/bergtatt/ind/i/fjeldkamrene 中的bergtattindifjeldkamrene)。

语法正确。根文件系统。就是这样。

问题 #1:我们现在应该如何进行路径名有效性?

在 Python 中验证路径名非常不直观。我在这里与Fake Name 完全一致:官方的os.path 包应该为此提供一个开箱即用的解决方案。由于未知(并且可能是令人不快的)原因,它没有。幸运的是,展开您自己的临时解决方案并不是 令人痛苦的......

好吧,确实如此。这很讨厌;它可能在发光时发出咯咯声和咯咯笑声。但是你要做什么? Nuthin'。

我们很快就会陷入低级代码的放射性深渊。但首先,让我们谈谈高级商店。标准的os.stat()os.lstat() 函数在传递无效路径名时会引发以下异常:

对于驻留在不存在目录中的路径名,FileNotFoundError 的实例。 对于位于现有目录中的路径名: 在 Windows 下,WindowsError 的实例winerror 属性为123(即ERROR_INVALID_NAME)。 在所有其他操作系统下: 对于包含空字节的路径名(即'\x00'),TypeError 的实例。 对于包含长度超过 255 个字节的路径组件的路径名,OSError 的实例errcode 属性为: 在 SunOS 和 *BSD 系列操作系统下,errno.ERANGE。 (这似乎是一个操作系统级别的错误,也称为 POSIX 标准的“选择性解释”。) 在所有其他操作系统下,errno.ENAMETOOLONG

至关重要的是,这意味着只有存在于现有目录中的路径名是可验证的。os.stat()os.lstat() 函数在传递驻留在不存在目录中的路径名时会引发通用 FileNotFoundError 异常,无论这些路径名是否无效。目录存在优先于路径名无效。

这是否意味着驻留在不存在目录中的路径名是可验证的?是的——除非我们修改这些路径名以驻留在现有目录中。然而,这甚至是安全可行的吗?修改路径名不应该阻止我们验证原始路径名吗?

要回答这个问题,请回想一下,ext4 文件系统上语法正确的路径名不包含包含空字节或 (B) 的路径组件长度为 255 个字节。因此,当且仅当该路径名中的所有路径组件都有效时,ext4 路径名才有效。这是大多数感兴趣的real-world filesystems。

这种迂腐的见解真的对我们有帮助吗?是的。它将一次性验证完整路径名的较大问题减少为仅验证该路径名中的所有路径组件的较小问题。通过遵循以下算法,任何任意路径名都是可验证的(无论该路径名是否驻留在现有目录中)以跨平台方式:

    将该路径名拆分为路径组件(例如,将路径名 /troldskog/faren/vild 拆分为列表 ['', 'troldskog', 'faren', 'vild'])。 对于每个这样的组件:
      将保证与该组件一起存在的目录的路径名加入到新的临时路径名中(例如,/troldskog)。 将该路径名传递给os.stat()os.lstat()。如果该路径名和该组件无效,则此调用保证引发暴露无效类型的异常,而不是通用的FileNotFoundError 异常。为什么? 因为该路径名位于现有目录中。(循环逻辑是循环的。)

是否有保证存在的目录?可以,但通常只有一个:根文件系统的最顶层目录(如上定义)。

将驻留在任何其他目录(因此不保证存在)中的路径名传递给os.stat()os.lstat() 会引发竞争条件,即使该目录先前已被测试存在。为什么?因为不能阻止外部进程同时删除该目录之后测试已经执行但之前路径名被传递给os.stat()os.lstat()。释放令人发狂的狗!

上述方法还有一个巨大的附带好处:安全性。不是很好吗?)具体来说:

通过简单地将这些路径名传递给os.stat()os.lstat() 来验证来自不受信任来源的任意路径名的前端应用程序容易受到拒绝服务 (DoS) 攻击和其他黑帽恶作剧的影响。恶意用户可能会尝试重复验证驻留在已知陈旧或缓慢的文件系统(例如 NFS Samba 共享)上的路径名;在这种情况下,盲目地声明传入的路径名可能最终会因连接超时而失败,或者会消耗更多的时间和资源,而不是您承受失业的微弱能力。

上述方法通过仅根据根文件系统的根目录验证路径名的路径组件来避免这种情况。 (即使那是陈旧、缓慢或不可访问的,你遇到的问题比路径名验证更大。)

迷路了? 太好了。让我们开始吧。 (假设为 Python 3。请参阅“What Is Fragile Hope for 300, leycec?”)

import errno, os

# Sadly, Python fails to provide the following magic number for us.
ERROR_INVALID_NAME = 123
'''
Windows-specific error code indicating an invalid pathname.

See Also
----------
https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
    Official listing of all such codes.
'''

def is_pathname_valid(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname for the current OS;
    `False` otherwise.
    '''
    # If this pathname is either not a string or is but is empty, this pathname
    # is invalid.
    try:
        if not isinstance(pathname, str) or not pathname:
            return False

        # Strip this pathname's Windows-specific drive specifier (e.g., `C:\`)
        # if any. Since Windows prohibits path components from containing `:`
        # characters, failing to strip this `:`-suffixed prefix would
        # erroneously invalidate all valid absolute Windows pathnames.
        _, pathname = os.path.splitdrive(pathname)

        # Directory guaranteed to exist. If the current OS is Windows, this is
        # the drive to which Windows was installed (e.g., the "%HOMEDRIVE%"
        # environment variable); else, the typical root directory.
        root_dirname = os.environ.get('HOMEDRIVE', 'C:') \
            if sys.platform == 'win32' else os.path.sep
        assert os.path.isdir(root_dirname)   # ...Murphy and her ironclad Law

        # Append a path separator to this directory if needed.
        root_dirname = root_dirname.rstrip(os.path.sep) + os.path.sep

        # Test whether each path component split from this pathname is valid or
        # not, ignoring non-existent and non-readable path components.
        for pathname_part in pathname.split(os.path.sep):
            try:
                os.lstat(root_dirname + pathname_part)
            # If an OS-specific exception is raised, its error code
            # indicates whether this pathname is valid or not. Unless this
            # is the case, this exception implies an ignorable kernel or
            # filesystem complaint (e.g., path not found or inaccessible).
            #
            # Only the following exceptions indicate invalid pathnames:
            #
            # * Instances of the Windows-specific "WindowsError" class
            #   defining the "winerror" attribute whose value is
            #   "ERROR_INVALID_NAME". Under Windows, "winerror" is more
            #   fine-grained and hence useful than the generic "errno"
            #   attribute. When a too-long pathname is passed, for example,
            #   "errno" is "ENOENT" (i.e., no such file or directory) rather
            #   than "ENAMETOOLONG" (i.e., file name too long).
            # * Instances of the cross-platform "OSError" class defining the
            #   generic "errno" attribute whose value is either:
            #   * Under most POSIX-compatible OSes, "ENAMETOOLONG".
            #   * Under some edge-case OSes (e.g., SunOS, *BSD), "ERANGE".
            except OSError as exc:
                if hasattr(exc, 'winerror'):
                    if exc.winerror == ERROR_INVALID_NAME:
                        return False
                elif exc.errno in errno.ENAMETOOLONG, errno.ERANGE:
                    return False
    # If a "TypeError" exception was raised, it almost certainly has the
    # error message "embedded NUL character" indicating an invalid pathname.
    except TypeError as exc:
        return False
    # If no exception was raised, all path components and hence this
    # pathname itself are valid. (Praise be to the curmudgeonly python.)
    else:
        return True
    # If any other exception was raised, this is an unrelated fatal issue
    # (e.g., a bug). Permit this exception to unwind the call stack.
    #
    # Did we mention this should be shipped with Python already?

完成。不要眯着眼睛看那段代码。 (它会咬人。

问题 #2:路径名的存在或可创建性可能无效,嗯?

鉴于上述解决方案,测试可能无效的路径名的存在或可创建性几乎是微不足道的。这里的小关键是调用之前定义的函数before测试通过的路径:

def is_path_creatable(pathname: str) -> bool:
    '''
    `True` if the current user has sufficient permissions to create the passed
    pathname; `False` otherwise.
    '''
    # Parent directory of the passed path. If empty, we substitute the current
    # working directory (CWD) instead.
    dirname = os.path.dirname(pathname) or os.getcwd()
    return os.access(dirname, os.W_OK)

def is_path_exists_or_creatable(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname for the current OS _and_
    either currently exists or is hypothetically creatable; `False` otherwise.

    This function is guaranteed to _never_ raise exceptions.
    '''
    try:
        # To prevent "os" module calls from raising undesirable exceptions on
        # invalid pathnames, is_pathname_valid() is explicitly called first.
        return is_pathname_valid(pathname) and (
            os.path.exists(pathname) or is_path_creatable(pathname))
    # Report failure on non-fatal filesystem complaints (e.g., connection
    # timeouts, permissions issues) implying this path to be inaccessible. All
    # other exceptions are unrelated fatal issues and should not be caught here.
    except OSError:
        return False

完成完成。除了不完全。

问题 #3:Windows 上的路径名存在或可写性可能无效

有一个警告。当然有。

正如官方os.access() documentation 承认的那样:

注意:即使os.access() 表明它们会成功,I/O 操作也可能会失败,特别是对于网络文件系统上的操作,其权限语义可能超出通常的 POSIX 权限位模型。

不出所料,Windows 是这里的常见嫌疑人。由于在 NTFS 文件系统上广泛使用访问控制列表 (ACL),简单的 POSIX 权限位模型很难映射到底层的 Windows 现实。虽然这(可以说)不是 Python 的错,但它可能仍然是与 Windows 兼容的应用程序的问题。

如果是您,需要更强大的替代方案。如果传递的路径存在,我们会尝试在该路径的父目录中创建一个保证立即删除的临时文件——更便携(如果昂贵)的可创建性测试:

import os, tempfile

def is_path_sibling_creatable(pathname: str) -> bool:
    '''
    `True` if the current user has sufficient permissions to create **siblings**
    (i.e., arbitrary files in the parent directory) of the passed pathname;
    `False` otherwise.
    '''
    # Parent directory of the passed path. If empty, we substitute the current
    # working directory (CWD) instead.
    dirname = os.path.dirname(pathname) or os.getcwd()

    try:
        # For safety, explicitly close and hence delete this temporary file
        # immediately after creating it in the passed path's parent directory.
        with tempfile.TemporaryFile(dir=dirname): pass
        return True
    # While the exact type of exception raised by the above function depends on
    # the current version of the Python interpreter, all such types subclass the
    # following exception superclass.
    except EnvironmentError:
        return False

def is_path_exists_or_creatable_portable(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname on the current OS _and_
    either currently exists or is hypothetically creatable in a cross-platform
    manner optimized for POSIX-unfriendly filesystems; `False` otherwise.

    This function is guaranteed to _never_ raise exceptions.
    '''
    try:
        # To prevent "os" module calls from raising undesirable exceptions on
        # invalid pathnames, is_pathname_valid() is explicitly called first.
        return is_pathname_valid(pathname) and (
            os.path.exists(pathname) or is_path_sibling_creatable(pathname))
    # Report failure on non-fatal filesystem complaints (e.g., connection
    # timeouts, permissions issues) implying this path to be inaccessible. All
    # other exceptions are unrelated fatal issues and should not be caught here.
    except OSError:
        return False

但是请注意,即使 这个 也可能还不够。

感谢用户访问控制 (UAC)、无与伦比的 Windows Vista 及其所有后续迭代blatantly lie 关于与系统目录有关的权限。当非管理员用户尝试在规范的 C:\WindowsC:\Windows\system32 目录中创建文件时,UAC 表面上允许用户这样做,而实际上将所有创建的文件隔离到该用户的个人资料。 (谁能想到欺骗用户会产生有害的长期后果?)

这太疯狂了。这是 Windows。

证明它

我们敢吗?是时候进行上述测试了。

由于 NULL 是面向 UNIX 的文件系统的路径名中唯一被禁止的字符,让我们利用它来证明冷酷的事实——忽略不可忽视的 Windows 恶作剧,坦率地说,这让我感到厌烦和愤怒:

>>> print('"foo.bar" valid? ' + str(is_pathname_valid('foo.bar')))
"foo.bar" valid? True
>>> print('Null byte valid? ' + str(is_pathname_valid('\x00')))
Null byte valid? False
>>> print('Long path valid? ' + str(is_pathname_valid('a' * 256)))
Long path valid? False
>>> print('"/dev" exists or creatable? ' + str(is_path_exists_or_creatable('/dev')))
"/dev" exists or creatable? True
>>> print('"/dev/foo.bar" exists or creatable? ' + str(is_path_exists_or_creatable('/dev/foo.bar')))
"/dev/foo.bar" exists or creatable? False
>>> print('Null byte exists or creatable? ' + str(is_path_exists_or_creatable('\x00')))
Null byte exists or creatable? False

超越理智。超越痛苦。您会发现 Python 的可移植性问题。

【讨论】:

是的,是我! 尝试将跨可移植路径名验证正则表达式组合在一起是徒劳的,并且对于常见的边缘情况肯定会失败。考虑 Windows 上的路径名长度,例如:“最大路径 32,767 个字符是近似值,因为 '\\?\' 前缀可能会在运行时被系统扩展为更长的字符串,并且这种扩展适用于总长度。”鉴于此,实际上技术上不可行构造一个只匹配有效路径名的正则表达式。改用 Python 更合理。 啊。我(不情愿地)明白了。你正在做一些比破解正则表达式更奇怪的事情。是的,that 肯定会更加失败。这也完全无法解决有问题的问题,即 not“如何从特定于 Windows 的基本名称中去除无效的子字符串?” (......由于您自己的遗漏,您未能解决 - 再次由于边缘情况)但是“我如何交叉移植测试路径名的有效性,以及对于有效路径名,这些路径的存在或可写性?”跨度> 文件系统特定的约束绝对是一个有效的问题——但它是双向的。对于使用来自不受信任来源的任意路径名的前端应用程序,盲目地执行读取充其量是一个冒险的提议。在这种情况下,强制使用根文件系统不仅明智而且谨慎。然而,对于其他应用程序,用户群可能足够值得信赖,可以授予不受限制的文件系统访问权限。我会说,这完全取决于上下文。感谢您敏锐地注意到这一点,Nobody!我将在上面添加一个警告。 至于命名法,我很喜欢在测试人员姓名前加上 is_。这是我的性格缺陷。尽管如此,适当地指出:你不能取悦所有人,有时你也无法取悦任何人。 ;) 在 Fedora 24、python 3.5.3 上,带有嵌入空字符的路径名抛出: ValueError: embedded null byte ...需要添加:``` 除了 ValueError as exc: return False ```在 TypeError 陷阱之前或之后。【参考方案2】:
if os.path.exists(filePath):
    #the file is there
elif os.access(os.path.dirname(filePath), os.W_OK):
    #the file does not exists but write privileges are given
else:
    #can not write there

请注意,path.exists 失败的原因可能不仅仅是the file is not there,因此您可能需要进行更精细的测试,例如测试包含目录是否存在等等。


在我与 OP 讨论后发现,主要问题似乎是文件名可能包含文件系统不允许的字符。当然,它们需要被删除,但 OP 希望在文件系统允许的情况下保持尽可能多的人类可读性。

遗憾的是,我不知道有什么好的解决方案。 不过,Cecil Curry's answer 会更仔细地检测问题。

【讨论】:

没有。如果路径中的文件存在,我需要返回 true,或者可以创建。如果路径无效(由于 Windows 上包含无效字符),我需要返回 false。 or can be created 好吧,我没有从你的问题中读到这一点。读取权限将在一定程度上依赖于平台。 @Fake Name:是的,它会删除一些平台依赖性,但仍然有一些平台提供其他平台不提供的东西,并且没有简单的方法来为所有平台打包。我更新了我的答案,看看那里。 我不知道为什么这个答案被赞成。它并没有远程接近解决核心问题——简而言之,就是:“请验证路径名?”验证路径权限在这里是一个辅助(并且在很大程度上可以忽略的)问题。虽然对 os.path.exists(filePath) 的调用在技术上确实会引发无效路径名的异常,但需要明确捕获这些异常并将其与其他不相关的异常区分开来。此外,同一调用在当前用户具有读取权限的现有路径上返回False。简而言之,就是坏事。 @CecilCurry:回答您的问题:查看问题的编辑历史记录。与大多数问题一样,一开始并没有那么明确,即使现在仅标题的措辞也可能与您所说的不同。【参考方案3】:

使用 Python 3,怎么样:

try:
    with open(filename, 'x') as tempfile: # OSError if file exists or is invalid
        pass
except OSError:
    # handle error here

使用“x”选项,我们也不必担心竞争条件。请参阅文档here。

现在,如果它不存在,这将创建一个非常短暂的临时文件 - 除非名称无效。如果你能接受它,它会简化很多事情。

【讨论】:

在这一点上,需要这个的项目已经远远超出了答案甚至相关的地步,以至于我无法真正接受答案。 具有讽刺意味的是,实际答案还不够好。无论如何,我想您可以查看该文件是否存在。如果是,请尝试将文件复制到其他位置,然后尝试覆盖。【参考方案4】:

找到一个名为 pathvalidate 的 PyPI 模块

https://pypi.org/project/pathvalidate/

pip install pathvalidate

它内部有一个名为 sanitize 的函数,它将获取文件路径并将其转换为有效的文件路径

from pathvalidate import sanitize_filepath
file1 = “ap:lle/fi:le”
print(sanitize_filepath(file1))
#will return apple/file

它也适用于保留名称。如果你给它提供 filePath con,它会返回 con_

因此,有了这些知识,我们可以检查输入的文件路径是否等于经过清理的文件路径,这意味着文件路径是有效的

import os
from pathvalidate import sanitize_filepath

def check(filePath):
    if os.path.exisits(filePath):
        return True
    if filePath == sanitize_filepath(filePath):
        return True
    return False

【讨论】:

这是一个很好的答案。但是,我可以安装pathvalidate,但它显示错误。 什么错误。我用 python 3.8 很好地下载了它【参考方案5】:
open(filename,'r')   #2nd argument is r and not w

如果文件不存在,将打开文件或给出错误。如果有错误,那么你可以尝试写入路径,如果你不能,那么你会得到第二个错误

try:
    open(filename,'r')
    return True
except IOError:
    try:
        open(filename, 'w')
        return True
    except IOError:
        return False

还可以查看here 了解 Windows 上的权限

【讨论】:

为了避免显式取消链接()测试文件的需要,您可以使用tempfile.TemporaryFile(),它会在临时文件超出范围时自动销毁它。 @FakeName 代码不同,我本可以在第二部分使用 os.access 但是如果你按照我给你的链接,你会发现这不是一个好主意,这会让你尝试实际打开写作路径的选项。 我正在使用os.path.join 构建我的路径,所以我没有 `\` 转义问题。此外,我并没有真正遇到目录 permission 问题。我遇到了目录(和文件名)name 问题。 @FakeName 在这种情况下你只需要尝试打开它(你不需要写),如果filename 包含无效字符,python 会出错。我已经编辑了答案 @HelgaIliashenko 打开写入将覆盖现有文件(使其为空),即使您立即关闭它而不写入它也是如此。这就是为什么我首先打开阅读,因为这样,如果你没有收到错误,那么你就知道有一个现有的文件。【参考方案6】:

尝试os.path.exists,这将检查路径,如果存在则返回True,如果不存在则返回False

【讨论】:

没有。如果路径上的文件存在,我需要返回 true,或者可以创建。如果路径无效(由于 Windows 上包含无效字符),我需要返回 false。 哪种类型的无效字符? 不知道 - 这是特定于平台的。 文件系统特定的,实际上。

以上是关于检查路径在 Python 中是不是有效,而不在路径的目标处创建文件的主要内容,如果未能解决你的问题,请参考以下文章

SAF DocumentFile - 检查路径是不是存在而不在每个文件夹级别创建每个 DocumentFile

Nodejs检查给定的字符串是不是是有效的文件系统路径而不实际检查文件系统

检查字符串是不是是有效的 Windows 目录(文件夹)路径

如何找到 Firebase Crashlytics 初始化文件路径并仔细检查它们是不是有效?

python 路径怎么设置,我的python2.7在usr-lip 下而不在usr-bin.path变量怎么设置求教

检查 path 是不是是目录路径(它可能不存在)