IT-Swarm.Net

如何检查文件是否存在而没有例外?

如何在不使用 try 语句的情况下查看文件是否存在?

4981
spence91

如果您检查的原因是这样,您可以执行类似if file_exists: open_it()的操作,那么在尝试打开它时使用try会更安全。在检查和尝试打开文件时检查然后打开文件被删除或移动的风险或介于两者之间的风险。

如果您不打算立即打开文件,可以使用 os.path.isfile

如果path是现有常规文件,则返回True。这遵循符号链接,因此 islink()isfile() 对于相同的路径都可以为true。

import os.path
os.path.isfile(fname) 

如果你需要确定它是一个文件。

从Python 3.4开始, pathlib模块 提供了一种面向对象的方法(在Python 2.7中向后移植到pathlib2):

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

要检查目录,请执行以下操作:

if my_file.is_dir():
    # directory exists

要检查Path对象是否存在,无论它是文件还是目录,请使用exists()

if my_file.exists():
    # path exists

您还可以在try块中使用resolve(strict=True)

try:
    my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
    # doesn't exist
else:
    # exists
4560
rslite

你有 os.path.exists function:

import os.path
os.path.exists(file_path)

这会为文件和目录返回True,但您可以改为使用

os.path.isfile(file_path)

测试它是否是一个特定的文件。它遵循符号链接。

1913
PierreBdR

isfile()exists() 将返回目录的True
因此,根据您是否只需要普通文件或目录,您将使用isfile()exists()。这是一个简单的REPL输出。

>>> print os.path.isfile("/etc/password.txt")
True
>>> print os.path.isfile("/etc")
False
>>> print os.path.isfile("/does/not/exist")
False
>>> print os.path.exists("/etc/password.txt")
True
>>> print os.path.exists("/etc")
True
>>> print os.path.exists("/does/not/exist")
False
885
bortzmeyer
import os.path

if os.path.isfile(filepath):
543
Paul

使用 os.path.isfile() with os.access()

import os
import os.path

PATH='./file.txt'

if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
else:
    print "Either the file is missing or not readable"
268
Yugal Jindle
import os
os.path.exists(path) # Returns whether the path (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not
248
benefactual

这是检查文件是否存在的最简单方法。只是 因为 当你检查时存在的文件没有 保证 当你需要打开它时它会在那里。

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")
145
un33k

Python 3.4+ 有一个面向对象的路径模块: pathlib 。使用此新模块,您可以检查文件是否存在,如下所示:

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

打开文件时,您可以(并且通常应该)仍然使用try/except块:

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

Pathlib模块中有很多很酷的东西:方便的通配,检查文件的所有者,更容易的路径连接等。值得一试。如果您使用的是较旧的Python(2.6或更高版本),您仍然可以使用pip安装pathlib:

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

然后导入如下:

# Older Python versions
import pathlib2 as pathlib
132
Cody Piersall

首选try语句。它被认为是更好的风格,避免了竞争条件。

不要拿我的话来。这个理论有很多支持。这是一对夫妇:

116
pkoch

如何在不使用try语句的情况下使用Python检查文件是否存在?

从Python 3.4开始提供,导入并使用文件名实例化Path对象,并检查is_file方法(请注意,对于指向常规文件的符号链接,这将返回True):

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

如果您使用的是Python 2,则可以从pypi, pathlib2 反向移植pathlib模块,或者从os.path模块中检查isfile

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

现在上面可能是这里最好的实用直接答案,但是有可能存在竞争条件(取决于你想要完成的事情),以及底层实现使用try这一事实,但Python在其中使用了try实现。

因为Python在任何地方使用try,所以没有理由避免使用它的实现。

但是这个答案的其余部分试图考虑这些警告。

更长,更迂腐的答案

自Python 3.4起可用,在Path中使用新的pathlib对象。请注意.exists不是很正确,因为目录不是文件(除了在unix意义上,everything是一个文件)。

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

所以我们需要使用is_file

>>> root.is_file()
False

这是is_file的帮助:

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

所以让我们得到一个文件,我们知道它是一个文件:

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

默认情况下,NamedTemporaryFile在关闭时删除文件(并且当不存在更多引用时将自动关闭)。

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

如果你深入研究 实现 ,你会看到is_file使用try

def is_file(self):
    """
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).
    """
    try:
        return S_ISREG(self.stat().st_mode)
    except OSError as e:
        if e.errno not in (ENOENT, ENOTDIR):
            raise
        # Path doesn't exist or is a broken symlink
        # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
        return False

比赛条件:为什么我们喜欢尝试

我们喜欢try,因为它避免了竞争条件。使用try,您只需尝试读取您的文件,期望它在那里,如果没有,您将捕获异常并执行任何有意义的回退行为。

如果要在尝试读取文件之前检查文件是否存在,并且可能正在删除它,然后您可能正在使用多个线程或进程,或者其他程序知道该文件并且可能删除它 - 您冒险a 竞争条件 如果你检查它是否存在,因为你是竞赛在它的条件(它的存在)改变之前打开它。

竞争条件很难调试,因为它有一个非常小的窗口,它可能导致程序失败。

但如果这是你的动机,那么can通过使用try上下文管理器获取suppress语句的值。

没有try语句避免竞争条件:suppress

Python 3.4为我们提供了 suppress 上下文管理器(以前是 ignore 上下文管理器),它在语义上在更少的行中完全相同,同时(至少表面上)满足原始的要求以避免try声明:

from contextlib import suppress
from pathlib import Path

用法:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

对于早期的Pythons,您可以滚动自己的suppress,但没有try将比使用更加冗长。我确实相信 这实际上是唯一没有在Python中任何级别使用try的答案 可以应用于Python 3.4之前,因为它使用了上下文管理器:

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

尝试可能更容易:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

其他选项不符合“不试”的要求:

isfile

import os
os.path.isfile(path)

来自 docs

os.path.isfile(path)

如果path是现有常规文件,则返回True。这遵循符号链接,因此islink()isfile()对于同一路径都可以为true。

但是如果你检查这个函数的 source ,你会发现它确实使用了一个try语句:

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

所有它正在使用给定的路径来查看它是否可以获取它的统计信息,捕获OSError然后检查它是否是一个文件,如果它没有引发异常。

如果您打算对该文件执行某些操作,我建议您尝试直接尝试它 - 除了避免竞争条件:

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

适用于Unix和Windows的是os.access,但要使用它必须传递标志,它不区分文件和目录。这更多用于测试真正的调用用户是否在提升的权限环境中具有访问权限:

import os
os.access(path, os.F_OK)

它也遇到与isfile相同的竞争条件问题。来自 docs

注意:使用access()检查用户是否有权获得例如在实际执行之前打开文件使用open()会创建一个安全漏洞,因为用户可能会利用检查和打开文件之间的短时间间隔来操作它。最好使用EAFP技术。例如:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

写得更好:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

避免使用os.access。它是一个低级函数,比上面讨论的更高级别的对象和函数有更多的用户错误机会。

对另一个答案的批评:

另一个答案是关于os.access

就个人而言,我更喜欢这个,因为在引擎盖下,它调用本机API(通过“$ {PYTHON_SRC_DIR} /Modules/posixmodule.c”),但它也为可能的用户错误打开了一个门,它不像其他变体那样是Pythonic :

这个答案说它更喜欢非Pythonic,容易出错的方法,没有任何理由。它似乎鼓励用户在不了解它们的情况下使用低级API。

它还创建了一个上下文管理器,通过无条件地返回True,允许所有异常(包括KeyboardInterruptSystemExit!)以静默方式传递,这是隐藏错误的好方法。

这似乎鼓励用户采用不良做法。

110
Aaron Hall
import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

导入os可以更轻松地导航并使用您的操作系统执行标准操作。

另请参阅 如何使用Python检查文件是否存在?

如果需要高级操作,请使用shutil

82
bishop

使用os.path.isfile()os.path.isdir()os.path.exists()测试文件和文件夹

假设“path”是有效路径,此表显示每个函数为文件和文件夹返回的内容:

enter image description here

您还可以使用os.path.splitext()测试文件是否是某种类型的文件以获取扩展名(如果您还不知道它)

>>> import os
>>> path = "path to a Word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True
75
Tom Fuller

在2016年,最好的方法仍然是使用os.path.isfile

>>> os.path.isfile('/path/to/some/file.txt')

或者在Python 3中,您可以使用pathlib

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...
67
KaiBuxe

看起来似乎没有try/except和isfile()之间有意义的功能差异,所以你应该使用哪一个有意义。

如果要读取文件,如果存在,请执行

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

但是如果你只是想重命名一个文件,如果它存在,因此不需要打开它,那就行了

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

如果要写入文件,如果它不存在,请执行

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

如果你需要文件锁定,那是另一回事。

62
chad

你可以尝试这个(更安全):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

输出将是:

([Errno 2]没有这样的文件或目录:'whatever.txt')

然后,根据结果,您的程序可以从那里继续运行,或者您可以编码以根据需要停止它。

53
philberndt

虽然我总是建议使用tryexcept语句,但这里有一些可能性(我个人最喜欢使用os.access):

  1. 尝试打开文件:

    打开文件将始终验证文件是否存在。你可以像这样制作一个函数:

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    如果它为False,它将在更高版本的Python中以无错的IOError或OSError停止执行。要捕获异常,必须使用try except子句。当然,你总是可以像这样使用try except`语句(感谢 hsandt 让我思考):

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. 使用os.path.exists(path)

    这将检查您指定的内容的存在。但是,它检查文件目录,因此请注意您如何使用它。

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. 使用os.access(path, mode)

    这将检查您是否有权访问该文件。它将检查权限。根据os.py文档,输入os.F_OK,它将检查路径是否存在。但是,使用此方法会创建一个安全漏洞,因为有人可以使用检查权限和打开文件之间的时间来攻击您的文件。您应该直接打开文件而不是检查其权限。 ( _ eafp _ vs _ lbyp _ )。如果您之后不打算打开文件,只检查其存在,那么您可以使用它。

    无论如何,这里:

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

我还要提一下,有两种方法可以验证文件是否存在。问题是permission deniedno such file or directory。如果你抓到IOError,设置IOError as e(就像我的第一个选项),然后输入print(e.args),这样你就可以确定你的问题了。我希望它有所帮助! :)

48
Zizouz212

日期:2017年12月4日

其他答案中列出了每种可能的解决方案。

检查文件是否存在的直观且有争议的方法如下:

import os
os.path.isfile('~/file.md')  # Returns True if exists, else False
# additionaly check a dir
os.path.isdir('~/folder')  # Returns True if the folder exists, else False
# check either a dir or a file
os.path.exists('~/file')

我做了一个详尽的备忘单供你参考:

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}
42
JawSaw

另外,os.access()

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

R_OKW_OKX_OK用于测试权限的标志( doc )。

32
zgoda

如果文件用于打开,您可以使用以下技术之一:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')

_ update _

为了避免混淆并根据我得到的答案,当前答案找到文件具有给定名称的目录。

30
bergercookie
if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

提升异常被认为是一种可接受的Pythonic方法,用于程序中的流量控制。考虑使用IOErrors处理丢失的文件。在这种情况下,如果文件存在但用户没有读取权限,则会引发IOError异常。

SRC: http://www.pfinn.net/python-check-if-file-exists.html

20
Pedro Lobito

你可以在没有try:的情况下写出Brian的建议。

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppress是Python 3.4的一部分。在旧版本中,您可以快速编写自己的抑制:

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass
17
Chris

如果您已将NumPy导入其他用途,则无需导入其他库,如pathlibospaths等。

import numpy as np
np.DataSource().exists("path/to/your/file")

这将根据其存在返回true或false。

17
durjoy

检查文件或目录是否存在

您可以遵循以下三种方式:

注1:os.path.isfile仅用于文件

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

注2:os.path.exists用于文件和目录

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

pathlib.Path方法(包含在Python 3+中,可以用Python 2的pip安装)

from pathlib import Path
Path(filename).exists()
16
Ali Hallaji

添加一个更微小的变化,这在其他答案中没有完全反映出来。

这将处理file_pathNone或空字符串的情况。

def file_exists(file_path):
    if not file_path:
        return False
    Elif not os.path.isfile(file_path):
        return False
    else:
        return True

根据Shahbaz的建议添加变体

def file_exists(file_path):
    if not file_path:
        return False
    else:
        return os.path.isfile(file_path)

根据Peter Wood的建议添加变体

def file_exists(file_path):
    return file_path and os.path.isfile(file_path):
15
Marcel Wilson

我是一个已经存在了大约10年的软件包的作者,它有一个直接解决这个问题的函数。基本上,如果您使用的是非Windows系统,则使用Popen来访问find。但是,如果您使用的是Windows,则会使用高效的文件系统walker复制find

代码本身不使用try块...除了确定操作系统,从而引导您进入“Unix”式find或手动find。时序测试显示try在确定操作系统时更快,所以我确实在那里使用了一个(但没有其他地方)。

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

而且文件......

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

如果你愿意,可以在这里实施: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190

15
Mike McKerns

这是Linux命令行环境的1行Python命令。我发现这非常好,因为我不是那么热的Bash家伙。

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

我希望这是有帮助的。

14

如何在不使用try语句的情况下检查文件是否存在?

在2016年,这仍然是检查文件是否存在以及文件是否是文件的最简单方法:

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfile实际上只是一个内部使用os.statstat.S_ISREG(mode)的辅助方法。此os.stat是一个较低级别的方法,它将为您提供有关文件,目录,套接字,缓冲区等的详细信息。 关于os.stat的更多信息

注意: 但是,这种方法不会以任何方式锁定文件,因此您的代码可能容易受到“ 检查时间 ”(_ tocttou _))错误。

因此,提高异常被认为是一种可接受的Pythonic方法,用于程序中的流量控制。人们应该考虑使用IOErrors处理丢失的文件,而不是if语句(只是一个建议)。

11
Inconnu

您可以使用Python的“OS”库:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False
11
Pradip Das
import os.path

def isReadableFile(file_path, file_name):
    full_path = file_path + "/" + file_name
    try:
        if not os.path.exists(file_path):
            print "File path is invalid."
            return False
        Elif not os.path.isfile(full_path):
            print "File does not exist."
            return False
        Elif not os.access(full_path, os.R_OK):
            print "File cannot be read."
            return False
        else:
            print "File can be read."
            return True
    except IOError as ex:
        print "I/O error({0}): {1}".format(ex.errno, ex.strerror)
    except Error as ex:
        print "Error({0}): {1}".format(ex.errno, ex.strerror)
    return False
#------------------------------------------------------

path = "/usr/khaled/documents/puzzles"
fileName = "puzzle_1.txt"

isReadableFile(path, fileName)
9
Khaled.K

您可以使用以下open方法检查文件是否存在+可读:

open(inputFile, 'r')
9
user3197473
import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

检查多个文件时这很有用。或者您想要与现有列表进行集合交叉/减法。

8
Jesvin Jose

要检查文件是否存在,

from sys import argv

from os.path import exists
script, filename = argv
target = open(filename)
print "file exists: %r" % exists(filename)
7
Hanson

您可以使用os.listdir检查文件是否在某个目录中。

import os
if 'file.ext' in os.listdir('dirpath'):
    #code
5
iPhynx
import os

# for testing purpose args defaulted to current folder & file. 
# returns True if file found
def file_exists(FOLDER_PATH='../', FILE_NAME=__file__):
    return os.path.isdir(FOLDER_PATH) \
        and os.path.isfile(os.path.join(FOLDER_PATH, FILE_NAME))

基本上是文件夹检查,然后使用 os.path.join 使用正确的目录分隔符进行文件检查。

4
Vimal Maheedharan

你一定要用这个。

from os.path import exists

if exists("file") == True:
    print "File exists."
Elif exists("file") == False:
    print "File doesn't exist."
3
user2154354

它可能不是必需的,但如果是的话,这里有一些代码

import os

def file_exists(path, filename):
    for file_or_folder in os.listdir(path):
        if file_or_folder == filename:
            return True
    return False
0
The dark side of Gaming