Como posso verificar o tamanho do arquivo em Python?


757

Estou escrevendo um script Python no Windows. Eu quero fazer algo com base no tamanho do arquivo. Por exemplo, se o tamanho for maior que 0, enviarei um email para alguém, caso contrário, continuarei para outras coisas.

Como verifico o tamanho do arquivo?


2
Path('./doc.txt').stat().st_size
Boris

Obrigado @Boris pela resposta moderna do Python (v3.4 +) :)
mab

Respostas:


735

Você precisa da st_sizepropriedade do objeto retornado poros.stat . Você pode obtê-lo usando pathlib(Python 3.4+):

>>> from pathlib import Path
>>> Path('somefile.txt').stat()
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> Path('somefile.txt').stat().st_size
1564

ou usando os.stat:

>>> import os
>>> os.stat('somefile.txt')
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> os.stat('somefile.txt').st_size
1564

A saída está em bytes.


2
Se houver algo, o valor pode ser passado como múltiplos do tamanho do bloco do sistema de arquivos (4096 bytes, por exemplo). Felizmente, ele é fornecido como bytes.
Josch

1
@josch - sim, isso é legal, pois o "tamanho em disco" pode ser multiplicado stat_result.st_blockspelo tamanho do bloco, mas ainda estou pesquisando como obtê-lo de forma programática e multiplataforma (não via tune2fsetc.)
Tomasz Gandor

1098

Usando os.path.getsize:

>>> import os
>>> b = os.path.getsize("/path/isa_005.mp3")
>>> b
2071611

A saída está em bytes.


124
Nota: a implementação de os.path.getsizeé simplesmentereturn os.stat(filename).st_size
wim 21/03

Portanto, há uma pequena perda de desempenho ao usar os.path.getsize, em oposição a os.stat (arquivo) .st_size?
wordsforthewise

5
@wordsforthewise medi-lo! ~ 150 ns no meu computador.
Davidmh 15/07/2015

@wordsforhewise, isso é mais um problema, se você também deseja obter outras informações sobre o arquivo (hora da modificação, tipo de arquivo, por exemplo) - então você pode obter tudo isso a partir de uma única chamada de sistema os.stat. Em seguida, a diferença pode executar em um número substancial de microssegundos :-)
Greggo

Se for chamado logo após a criação de um arquivo, ele retornará 0 @danben
alper

131

As outras respostas funcionam para arquivos reais, mas se você precisar de algo que funcione para "objetos semelhantes a arquivos", tente o seguinte:

# f is a file-like object. 
f.seek(0, os.SEEK_END)
size = f.tell()

Funciona para arquivos reais e StringIO, em meus testes limitados. (Python 2.7.3.) A API "objeto semelhante a arquivo" não é realmente uma interface rigorosa, é claro, mas a documentação da API sugere que objetos semelhantes a arquivo devem suportar seek()e tell().

Editar

Outra diferença entre isso e os.stat()é que você pode stat()criar um arquivo mesmo que não tenha permissão para lê-lo. Obviamente, a abordagem de procurar / avisar não funcionará, a menos que você tenha permissão de leitura.

Editar 2

Por sugestão de Jonathon, aqui está uma versão paranóica. (A versão acima deixa o ponteiro do arquivo no final do arquivo, portanto, se você tentar ler o arquivo, receberá zero bytes de volta!)

# f is a file-like object. 
old_file_position = f.tell()
f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(old_file_position, os.SEEK_SET)

8
Você não precisa importar os, em vez disso, escreva f.seek(0, 2)para buscar 0 bytes no final.
precisa saber é o seguinte

2
E para a última linha, se osnão for usada:f.seek(old_file_position, 0)
luckydonald

48
Se você usar literais inteiros em vez de variáveis ​​nomeadas, estará torturando alguém que precise manter seu código. Não há motivo convincente para não importar os.
Mark E. Haase

Obrigado pela solução, eu implementei e está funcionando bem. Só para confirmar, a sizesaída está em bytes?
Kedar.Aitawdekar #

3
Aparentemente, esta é, pelo menos, um pouco arriscado, dependendo de como implementos Python #seek(): wiki.sei.cmu.edu/confluence/display/c/...
Autumnsault

72
import os


def convert_bytes(num):
    """
    this function will convert bytes to MB.... GB... etc
    """
    for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
        if num < 1024.0:
            return "%3.1f %s" % (num, x)
        num /= 1024.0


def file_size(file_path):
    """
    this function will return the file size
    """
    if os.path.isfile(file_path):
        file_info = os.stat(file_path)
        return convert_bytes(file_info.st_size)


# Lets check the file size of MS Paint exe 
# or you can use any file path
file_path = r"C:\Windows\System32\mspaint.exe"
print file_size(file_path)

Resultado:

6.1 MB

5
this function will convert bytes to MB.... GB... etcErrado. Esta função irá converter bytes para MiB, GiB, etc. Veja este post .
moi

2
A linha 10 pode ser alterada para return f'{num:.1f} {x}'em Python> = 3.5.
Matt M.

53

Usando pathlib( adicionado no Python 3.4 ou em um backport disponível no PyPI ):

from pathlib import Path
file = Path() / 'doc.txt'  # or Path('./doc.txt')
size = file.stat().st_size

Esta é realmente apenas uma interface os.stat, mas o uso pathlibfornece uma maneira fácil de acessar outras operações relacionadas a arquivos.


18

Existe um bitshifttruque que eu uso se quiser converter de bytespara qualquer outra unidade. Se você faz o turno certo, 10basicamente o desloca por um pedido (múltiplo).

Exemplo: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)

9
Isso não responde à pergunta. A questão é encontrar o tamanho de um arquivo, não formatar o resultado para consumo humano.
que você precisa

1
Esses números estão errados e, portanto, confusos. 5 GB são 5e9 bytes. Isso deveria ser algum tipo de aproximação legível por humanos? Onde você usaria algo assim?
Dre

1 bit => 2 ... 2 bits => 4 ... 3 bits => 8 ... 4 bits => 16 ... 5 bits => 32 ... 6 bits => 64 ... 7 bits => 128 ... 8 bits => 256 ... 9 bits => 512 ... 10 bits => 1024 ... 1024 bytes é 1kB ... => 20 -bits => 1024 * 1024 = 1.048.576 bytes, que é 1024kB e 1 MB ... => 30 bits => 1024 * 1024 * 1024 = 1.073.741.824 bytes, que são 1.048.576 kB e 1024MB e 1 GB ... Você confundiu notação científica e casas decimais com a representação binária / base-2 usada na computação. 5x9 = 5 x 10 ^ 9 = 5.000.000.000
James 'Fluffy' Burton

3
Gente, ele não confundiu nada ... ele acabou de dar uma aproximação, o que é evidente quando ele diz "basicamente". 2 ^ 10 é de aprox. 10 ^ 3. De fato, essa aproximação é tão comum que tem um nome : Mebi , Gibi e Tebi são Mega, Giga e Tera, respectivamente. Em relação a não responder à pergunta, @WillManley, você tem um ponto justo lá! ;-p
Mike Williamson

9

Seguindo rigorosamente a pergunta, o código Python (+ pseudo-código) seria:

import os
file_path = r"<path to your file>"
if os.stat(file_path).st_size > 0:
    <send an email to somebody>
else:
    <continue to other things>

-1
#Get file size , print it , process it...
#Os.stat will provide the file size in (.st_size) property. 
#The file size will be shown in bytes.

import os

fsize=os.stat('filepath')
print('size:' + fsize.st_size.__str__())

#check if the file size is less than 10 MB

if fsize.st_size < 10000000:
    process it ....

-1

nós temos duas opções Ambos incluem a importação do módulo os

1) A função import os como os.stat () retorna um objeto que contém tantos cabeçalhos, incluindo o tempo de criação do arquivo e o horário da última modificação, etc. Entre eles, st_size () fornece o tamanho exato do arquivo.

os.stat ("nome do arquivo"). st_size ()

2) import os Neste, temos que fornecer o caminho exato do arquivo (caminho absoluto), não um caminho relativo.

os.path.getsize ("caminho do arquivo")

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.