path.exists() 返回 False

27

我正在构建一个基本的文件服务器,但我的程序找不到文件。

def sendfile(sock, myfile):
    print 'Serving file:', myfile
    print 'File exists?:', os.path.exists(myfile)

    path = os.path.normpath(os.path.join(os.getcwd(), myfile))
    print 'Serving file:', path
    print 'File exists?:', os.path.exists(path)
这些代码总是返回False,即使'myfile'和'path'是正确的[文件与服务器程序在同一目录下]。
IDLE正常工作,但不适用于传递到函数中。
>>> print os.path.exists("/user/server/foo.txt")  
True

我错过了什么?

[编辑:] 输出:

Serving file: foo.txt

File exists?: False
Serving file: /user/server/foo.txt

File exists?: False

1
你能给我们提供那些打印语句的完整输出吗? - BostonJohn
myfile 究竟是什么?/user/server/foo.txt - Pierre GM
1
  1. 你为什么要编写一个基本文件服务器?<现有的所有优秀文件服务器>呢?
  2. myfile是否作为绝对路径传递?
  3. 在函数内部尝试使用import pdb; pdb.set_trace(),并检查本地范围。
- sapht
3
path末尾是否有换行符?在将path传递给os.path.exists之前,尝试去除路径中的空格。 - Thane Brimhall
此外,Python 对路径被引号包含这一点很挑剔。os.system(r"C:\My documents") 是正确的,但是 os.listdir(r"C:\My documents") 将会返回错误信息。 - illan
10个回答

28

我几乎可以确定你在检查路径是否存在之前没有对你的输入进行过滤。这是我在解释器中运行的代码:

>>> from os.path import exists
>>> exists('dog.png')
True
>>> exists('dog.png\n')
False
尝试在检查存在性之前清除path上的空格。

此外,Python 对路径加引号表示不满意。os.system(r"C:\My documents") 是正确的,但 os.listdir(r"C:\My documents") 会返回错误。 - illan

16

如果你阅读Python文档中的os.path.exists(),它会指出有一些特定情况下文件或文件夹存在但是os.path.exists()返回false:

如果path指向一个现有路径或打开的文件描述符,则返回True。对于损坏的符号链接返回False。在某些平台上,即使物理路径存在,如果没有权限执行所请求文件的os.stat(),则此函数可能返回False。


好主意。如果使用pathlib.Path.exists而不是os.exists,当它在self.stat()调用时触发PermissionDenied错误,将有助于解决os.stat失败的问题。 - 10mjg

11

虽然这并没有直接回答这里提出的问题,但我在使用strip()或os.path.join()后仍发现os.path.exists()始终返回"False"时找到了这个主题。在我的情况下,我正在使用~(波浪符)指向主目录,就像这样:

fileName = "~/path/to/file.txt"

修复这个问题的最好方法是使用os.path.expanduser(fileName),然后检查文件是否存在。或者可以通过使用os.path.abspath()恢复绝对路径,然后从路径中移除“~”(但此解决方案并不适用于所有情况)。

os.path.exists(os.path.abspath(fileName).replace("~",""))

也许这会对某些人有所帮助。


3

这个答案中所述,主要是由于空格导致的。

我也遇到了这个问题。花了很多时间才找出来。

Python 有一个名为 strip() 的函数,它可以去除空格。

如果变量 path_to_file 包含实际文件的路径,则尝试使用:

if path.exists(path_to_file.strip())
        print("file exists")
else:
        print("file doesn't exist")

这对我有用。

2

这可能不能直接回答你的问题,但是你可以采用"try/except"方法:无论哪个函数使用文件,如果文件不存在(特别是内置函数),该函数应返回异常,然后您可以相应地采取行动。这样您就不需要自己检查文件是否存在。是否危险?也许,但这取决于您实际想要做什么。


1

我经常遇到这个问题,但尝试添加getcwd()之后,现在它再也没有失败过。

os.path.join(os.getcwd(), source_file)

1

如果给定的路径超过256个字符,os.path.exists也会返回false。


1
我相信这只适用于Windows 10 v1607之前的32位操作系统。在此之后,MAX_PATH限制扩展到32000个字符。更多信息请参考:https://learn.microsoft.com/pt-br/windows/win32/fileio/maximum-file-path-limitation - undefined

1

如果由于空格问题而导致失败,这实际上应该被视为一个 bug。

我发现,在某些情况下,结果可能是虚假的,这取决于文件服务器的状态。这种情况并不总是发生,只是偶尔会出现。

我发现,至少延迟10秒钟可以避免失败。在这种情况下,我反复打开 zip 归档文件以访问特定的压缩文件。在尝试打开文件之前,它会检查路径是否存在(由于此奇怪的问题而使用了 try 语句)。如果失败,则会在一个循环中等待,并增加延迟时间。我发现,通常会在4次循环后(10秒延迟)再次找到文件存在。

这里是我的循环打印语句的输出:

Archive r:\ballotimagearchive\ca_san_francisco_2020_pri\d03.zip does not exist according to os.path.exists().
Waiting 1 seconds
Waiting 2 seconds
Waiting 3 seconds
Waiting 4 seconds
After wait of 10 secs, r:\ballotimagearchive\ca_san_francisco_2020_pri\d03.zip now exists according to os.path.exists().

这是代码产生此效果的片段。
    if os.path.isfile(source_path):
    print(f"Verified that {source_path} exists.")
else:
    print(f"Archive {source_path} does not exist according to os.path.exists().")

    # this may be a spurious problem related to using a file server.

    tot_time = 0
    for i in range(1,20):
        print(f"Waiting {i} seconds")
        time.sleep(i)
        tot_time += i 
        if os.path.isfile(source_path):
            print(f"After wait of {tot_time} secs, {source_path} now exists according to os.path.exists().")
            break
    else:
        print(f"After wait of {tot_time} secs, {source_path} still not found according to os.path.exists().")
        sys.exit(1)

我刚刚也注意到了同样的事情...相同的文件名,没有更改,但在运行数小时后出现了一个虚假的不存在。我使用文件的存在来保持线程活动,因此每隔30秒左右会进行检查。这就像平台中的某些东西由于高负载问题或访问争用而超时了一样。看完你的评论后,我打算增加双重检查的延迟时间。 - Rob

0

我想在Ubuntu的Downloads文件夹中使用文件,但是os.path.exists无法使用绝对路径~/Downloads/filename.txt找到它。

然后我使用os.path.abspath('')获取根路径/home/yourPCname/并替换~,这样就可以了!


0
我曾经遇到过同样的问题,并找到了以下解决方案:
即使在Windows上,使用操作系统的本地目录分隔符'\'或'/',在所有情况下都使用正斜杠对我来说都可以正常工作。os.sep可以帮助。
除此之外,对路径字符串进行一些类似于这样的净化处理:
import re
from os import path
strPath = "c:/dir1/dir2/dir3/dir4/important-file.ext"
strPath = re.escape(strPath)

bTest = os.access(strPath, os.F_OK)

# or the classic
bTest = path.exists(strPath)
print(bTest)



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接