如何检查文件是否为空?

405

我有一个文本文件,如何检查它是否为空?

12个回答

505
>>> import os
>>> os.stat("file").st_size == 0
True

3
可以的,但我不想导入stat库。原因是这段代码已经简洁明了了,并且返回列表中元素的大小和位置不会很快改变。 - ghostdog74
9
请注意,文件类型同样适用于json。有时,对于空文件,json.load()无法正常工作,这提供了一种处理该情况的好方法。 - seokhoonlee
6
如果字符串中有换行符,那么它实际上并不是空的。 - sappjw
有时候文件的大小即使为空也会是4Kib。 - alper
打开文件,使用read()读取并检查长度是否为零是不好的做法。 - Or b
显示剩余3条评论

157
import os    
os.path.getsize(fullpathhere) > 0

8
为了安全起见,你可能需要捕获 OSError 并返回 False。 - kennytm
7
使用这个与使用os.stat('file').st_size有什么区别/优势? - Elijah Lynn
4
看起来在底层实现上这两个是相同的:https://dev59.com/aWMk5IYBdhLWcg3wyw7H#18962257 - 1''
即使文件为空,此操作也会返回20。 - alper
3
@alper所说的“20”指的是一个经过gzip压缩的空文件的大小。如果您的文件确实为空,使用ls -l(或在Windows上使用dir)命令会报告大小为0,同时os.path.getsize()也会返回0。请注意,这里只是指真正的空文件,而不是仅仅没有文本内容的文件。 - joanis

94

getsize()stat()都会在文件不存在时抛出异常。这个函数不会抛出异常,返回True/False(更简单但不够健壮):

import os
def is_non_zero_file(fpath):  
    return os.path.isfile(fpath) and os.path.getsize(fpath) > 0

绝对喜欢使用os.path.getsize() - David Gay
19
由于在调用os.path.isfile(fpath)os.path.getsize(fpath)之间,文件可能会被删除,因此存在竞态条件,如果发生这种情况,所提出的函数将引发异常。 - s3rvac
5
最好尝试捕获OSError,就像另一篇评论中提出的那样。 - j08lue
还需要捕获 TypeError,因为如果输入的 fpath 是 None,就会引发此异常。 - Trutane

54

如果你正在使用Python 3和pathlib,你可以使用os.stat()信息,使用Path.stat()方法,该方法具有属性st_size(文件大小以字节为单位):

>>> from pathlib import Path
>>> mypath = Path("path/to/my/file")
>>> mypath.stat().st_size == 0 # True if empty

38
如果由于某种原因您已经打开了该文件,您可以尝试以下操作:
>>> with open('New Text Document.txt') as my_file:
...     # I already have file open at this point.. now what?
...     my_file.seek(0) # Ensure you're at the start of the file..
...     first_char = my_file.read(1) # Get the first character
...     if not first_char:
...         print "file is empty" # The first character is the empty string..
...     else:
...         my_file.seek(0) # The first character wasn't empty. Return to the start of the file.
...         # Use file now
...
file is empty

正是我遇到的情况...在检查文件后,指针跳过了第一个字符,导致最终输出让我感到困惑...谢谢您... - Nikhil Ravindran

16

如果您拥有文件对象,则

>>> import os
>>> with open('new_file.txt') as my_file:
...     my_file.seek(0, os.SEEK_END) # go to end of file
...     if my_file.tell(): # if current position is truish (i.e != 0)
...         my_file.seek(0) # rewind the file for later use 
...     else:
...         print "file is empty"
... 
file is empty

2
这个答案应该有更多的投票,因为它实际上检查了文件是否有任何内容。 - amanb

12

结合 ghostdog74的答案 和评论:

>>> import os
>>> os.stat('c:/pagefile.sys').st_size==0
False

False表示一个非空文件。

因此,让我们编写一个函数:

import os

def file_is_empty(path):
    return os.stat(path).st_size==0

4

由于您没有定义什么是空文件:有些人可能认为只有空白行的文件也是空文件。因此,如果您想检查您的文件是否仅包含空白行(任何空格字符、'\r'、'\n'、'\t'),您可以按照以下示例进行操作:

Python 3

import re

def whitespace_only(file):
    content = open(file, 'r').read()
    if re.search(r'^\s*$', content):
        return True

解释:上面的例子使用正则表达式(regex)匹配文件的内容(content)。

具体来说:对于整个正则表达式^\s*$,如果文件只包含空白行和/或空白字符,则表示匹配成功。

  • ^ 断言该位置在行首
  • \s 匹配任何空格字符(等同于 [\r\n\t\f\v ])
  • * 量词——匹配零次或多次,尽可能多地匹配(贪婪模式)
  • $ 断言该位置在行尾

3
我投反对票是因为:1- 没有必要定义一个空文件:它是一个没有内容的文件。包含空行的文件不是空文件。2- 这会将整个文件读入内存中。 - bfontaine
1
我认为这也是一个不好的答案。因为它只适用于真正空白的文件。但是一旦文件不是空白的,你可能会遇到许多错误,其中之一是“UnicodeDecodeError”。请小心使用此解决方案。 - hotenov

3

一个重要的陷阱:使用 getsize()stat() 函数测试时,压缩的空文件 会显示为非零:

$ python
>>> import os
>>> os.path.getsize('empty-file.txt.gz')
35
>>> os.stat("empty-file.txt.gz").st_size == 0
False

$ gzip -cd empty-file.txt.gz | wc
0 0 0

所以你应该检查要测试的文件是否已被压缩(例如,检查文件名后缀),如果是,则要么退出程序,要么将其解压缩到临时位置,测试未压缩的文件,完成后删除该文件。

测试压缩文件大小的更好方法:直接使用适当的压缩模块读取它。你只需要读取文件的第一行,例如


1
你在这里介绍了一个不错的陷阱! - Ron Klein

2
如果您想检查一个CSV文件是否为空,可以尝试以下代码:
with open('file.csv', 'a', newline='') as f:
    csv_writer = DictWriter(f, fieldnames = ['user_name', 'user_age', 'user_email', 'user_gender', 'user_type', 'user_check'])
    if os.stat('file.csv').st_size > 0:
        pass
    else:
        csv_writer.writeheader()

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