Размер открытого файлового объекта

Есть ли способ узнать размер файлового объекта, который в данный момент открыт?

В частности, я работаю с модулем tarfile для создания tar-файлов, но я не хочу, чтобы мой tar-файл превышал определенный размер. Насколько я знаю, объекты tarfile похожи на файлы, поэтому я думаю, что универсальное решение будет работать.


person strider1551    schedule 12.11.2008    source источник


Ответы (5)


$ ls -la chardet-1.0.1.tgz
-rwxr-xr-x 1 vinko vinko 179218 2008-10-20 17:49 chardet-1.0.1.tgz
$ python
Python 2.5.1 (r251:54863, Jul 31 2008, 22:53:39)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('chardet-1.0.1.tgz','rb')
>>> f.seek(0,2)
>>> f.tell()
179218L

Добавление идеи ChrisJY в пример

>>> import os
>>> os.fstat(f.fileno()).st_size
179218L
>>>        

Примечание. Судя по комментариям, f.seek(0, 2) необходимо перед вызовом f.tell(), без которого он вернул бы размер 0. Причина в том, что f.seek(0, 2) перемещает позицию файлового объекта в конец файла.

person Vinko Vrsalovic    schedule 12.11.2008
comment
docs.python.org/library/stat.html#stat.ST_SIZE os.fstat вернуть stat структуру, пожалуйста, используйте st_size - person shevski; 11.10.2011
comment
Кто-нибудь может пролить свет на магию f.seek(0,2)? Почему tell() возвращает 0 без него? - person previous_developer; 31.08.2015
comment
@m_poorUser f.seek(0, 2) перемещает позицию объекта файла на 0 байтов от конца файла, поэтому позиция объекта файла находится в конце файла. Затем f.tell() возвращает текущую позицию файлового объекта, которая в данном случае является размером файла. См. docs.python.org/2/tutorial/< /а> - person EarlCrapstone; 23.09.2015
comment
f.seek(...) возвращает абсолютную позицию. Не нужно следовать за f.tell(). Попробуйте это: print(f.seek(0, 2)) и вы увидите. - person IAbstract; 04.03.2016
comment
@IAbstract — это новое в Python3. В Python2 f.seek ничего не возвращает, независимо от того, какие аргументы вы ему передаете. Таким образом, f.tell() следует хранить по мере необходимости! - person hjc1710; 23.03.2016
comment
В Python 3.6, хотя BufferedIO и RawIO вы можете использовать .tell() для оценки размера файла, по определению он возвращает текущую позицию в потоке в виде непрозрачного числа. И это число обычно не представляет количество байтов в базовом двоичном хранилище для TextIO. к вашему сведению. - person Devy; 09.01.2017
comment
Пример был бы более понятным, если бы f.seek(0, 2) было записано как f.seek(0, os.SEEK_END). - person Juuso Ohtonen; 03.09.2018
comment
Вам не нужен tell(), потому что seek() уже возвращает позицию, на которую он был установлен. - person Bachsau; 30.08.2019
comment
Напишите f.seek(0,0) после file_size = f.seek(0,2), если вы планируете использовать файл позже. - person F. Vosnim; 06.07.2020

Что ж, если файловый объект поддерживает метод tell, вы можете сделать:

current_size = f.tell()

Это скажет вам, где он в настоящее время пишет. Если вы пишете последовательно, это будет размер файла.

В противном случае вы можете использовать возможности файловой системы, т.е. os.fstat, как предлагают другие.

person PierreBdR    schedule 12.11.2008
comment
current_size — неправильное имя переменной, поскольку оно означает текущий размер файла. tell() указывает текущую позицию файлового потока, то есть место, где будет происходить следующее чтение/запись. - person IAbstract; 03.03.2016
comment
Согласно документу Python 3.6, .tell() Return the current stream position as an opaque number. The number does not usually represent a number of bytes in the underlying binary storage. - person Devy; 09.01.2017

Если у вас есть дескриптор файла, вы можете использовать fstat, чтобы узнать размер, если он есть. Более общее решение — перейти к концу файла и прочитать его местоположение там.

person Chris Jester-Young    schedule 12.11.2008

Другим решением является использование StringIO, «если вы выполняете операции в памяти».

with open(file_path, 'rb') as x:
    body = StringIO()
    body.write(x.read())
    body.seek(0, 0)

Теперь body ведет себя как файловый объект с различными атрибутами, такими как body.read().

body.len указывает размер файла.

person vestronge    schedule 17.08.2016

person    schedule
comment
Я использую это, чтобы получить размер файла, над которым я работаю. Если я помещу ваш пример в такой with блок -- with open('1_notmnist.ipynb', 'rb') as f: print(len(f.read())) -- он закроет мой файл, когда я его запущу? Или он просто закроет отдельный экземпляр файла, который он создает? Точнее, нужно ли закрывать файл, открытый этой командой? Я хочу сохранить копию файла, над которым я работаю, открытой. - person Karl Baker; 30.01.2019
comment
Да, когда вы используете with open(...) в конце, файл автоматически закрывается. - person Alex Prusyazhnyk; 02.02.2019
comment
ОП хочет ограничить размер файлов. Чтение всего файла, когда он может оказаться слишком большим, — плохая идея! Здесь уже есть ответы, которые получают размер файла без чтения всего файла и, возможно, нехватки памяти. - person Stefan; 04.03.2019